package xcmg.device.service.delivery;

import com.github.pagehelper.PageInfo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xcmg.device.dao.entity.DataDictionaryDO;
import xcmg.device.dao.entity.account.ArapDO;
import xcmg.device.dao.entity.account.ArapDetailDO;
import xcmg.device.dao.entity.basic.SystemParameter;
import xcmg.device.dao.entity.company.CompanyDealerDO;
import xcmg.device.dao.entity.delivery.DeliveryNoteDO;
import xcmg.device.dao.entity.delivery.DeliveryNoteDetailDO;
import xcmg.device.dao.entity.delivery.DeliveryNoteExportDO;
import xcmg.device.dao.entity.delivery.DeliveryReceiptDO;
import xcmg.device.dao.entity.delivery.DeliveryReceiptMaterialDO;
import xcmg.device.dao.entity.marketing.MarketingActivityDO;
import xcmg.device.dao.entity.purchase.PurchaseRequestDO;
import xcmg.device.dao.entity.sale.SaleIntentionDO;
import xcmg.device.dao.entity.sale.SaleIntentionDetailDO;
import xcmg.device.dao.entity.warehouse.WarehouseDeliveryDO;
import xcmg.device.dao.mapper.CompanyDealerMapper;
import xcmg.device.dao.mapper.CompanyInfoMapper;
import xcmg.device.dao.mapper.DataDictionaryMapper;
import xcmg.device.dao.mapper.MarketingActivityMapper;
import xcmg.device.dao.mapper.MarketingMaterialsMapper;
import xcmg.device.dao.mapper.MaterialLocationRelationMapper;
import xcmg.device.dao.mapper.PurchaseRequestMapper;
import xcmg.device.dao.mapper.SaleIntentionDetailMapper;
import xcmg.device.dao.mapper.SaleIntentionMapper;
import xcmg.device.dao.mapper.account.ArapDetailMapper;
import xcmg.device.dao.mapper.account.ArapMapper;
import xcmg.device.dao.mapper.delivery.DeliveryNoteDetailMapper;
import xcmg.device.dao.mapper.delivery.DeliveryNoteMapper;
import xcmg.device.dao.mapper.delivery.DeliveryReceiptLinkMapper;
import xcmg.device.dao.mapper.delivery.DeliveryReceiptMapper;
import xcmg.device.dao.mapper.delivery.DeliveryReceiptMaterialMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseAreaLocationDOMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseDeliveryDetailMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseDeliveryMapper;
import xcmg.device.infra.DateUtil;
import xcmg.device.infra.ErrorCode;
import xcmg.device.infra.ExportUtil;
import xcmg.device.infra.HttpRequestUtil;
import xcmg.device.infra.enums.BillDesc;
import xcmg.device.infra.enums.DeliveryNoteAuditStatusEnum;
import xcmg.device.infra.enums.DeliveryNoteOutStatusEnum;
import xcmg.device.infra.enums.DeliveryStatus;
import xcmg.device.infra.enums.ForwardBarcodeLableEnum;
import xcmg.device.service.GenDocumentService;
import xcmg.device.service.basic.SystemParameterService;
import xcmg.device.service.company.CompanyDealerService;
import xcmg.device.service.company.CompanyInfoService;
import xcmg.device.service.sale.SaleIntentionService;
import xcmg.device.service.vo.basic.MaterialLocationRelationVO;
import xcmg.device.service.vo.company.CompanyInfoVO;
import xcmg.device.service.vo.delivery.DeliveryNoteAddVO;
import xcmg.device.service.vo.delivery.DeliveryNoteDetailVO;
import xcmg.device.service.vo.delivery.DeliveryNoteVO;
import xcmg.device.service.vo.delivery.DeliveryReceiptMaterialVO;
import xcmg.device.service.vo.delivery.ExportDeliveryDetailsVO;
import xcmg.device.service.vo.marketing.MarketingMaterialsVO;
import xcmg.device.service.vo.permission.WareHousePermission;
import xcmg.device.service.vo.sale.InformVO;
import xcmg.device.service.vo.warehouse.FindMaterialsInfos;
import xcmg.device.service.vo.warehouse.FindMaterialsNumParam;
import xcmg.device.service.vo.warehouse.app.EnableAndOccupyVO;
import xcmg.device.service.warehouse.DepartmentWarehouseRelationService;
import xcmg.device.service.warehouse.WarehouseDeliveryService;
import xcmg.device.service.warehouse.WarehouseInventoryService;
import xcmg.device.service.warehouse.allot.RegionAllotService;
import xcmg.device.util.CompanyUtil;
import xcmg.device.util.DecimalUtil;
import yb.ecp.fast.feign.AuthClient;
import yb.ecp.fast.feign.FastGenClient;
import yb.ecp.fast.infra.infra.ActionResult;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;
import yb.ecp.fast.infra.infra.log.LogHelper;
import yb.ecp.fast.infra.util.ListUtil;
import yb.ecp.fast.infra.util.PageHelperPlus;
import yb.ecp.fast.infra.util.StringUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static xcmg.device.infra.StringUtil.join;

@Service

public class DeliveryNoteService {

    @Autowired
    private CompanyInfoService companyInfoService;
    @Autowired
    private CompanyDealerMapper companyDealerMapper;
    @Autowired
    private CompanyInfoMapper companyInfoMapper;

    @Autowired
    private DeliveryNoteMapper deliveryNoteMapper;

    @Autowired
    private DeliveryNoteDetailMapper deliveryNoteDetailMapper;

    @Autowired
    private FastGenClient fastGenClient;

    @Autowired
    private GenDocumentService genDocumentService;

    @Autowired
    private HttpServletResponse response;

    @Autowired
    private WarehouseDeliveryMapper warehouseDeliveryMapper;

    @Autowired
    private WarehouseDeliveryDetailMapper warehouseDeliveryDetailMapper;

    @Autowired
    private DataDictionaryMapper dataDictionaryMapper;

    @Autowired
    private SaleIntentionService saleIntentionService;
    @Autowired
    private SaleIntentionDetailMapper saleIntentionDetailMapper;

    @Autowired
    private DeliveryNoteService deliveryNoteService;

    @Autowired
    private WarehouseInventoryService warehouseInventoryService;

    @Autowired
    private WarehouseDeliveryService warehouseDeliveryService;

    @Autowired
    private MarketingActivityMapper marketingActivityMapper;

    @Autowired
    private MaterialLocationRelationMapper materialLocationRelationMapper;


    @Autowired
    private MarketingMaterialsMapper marketingMaterialsMapper;

    @Autowired
    private ArapMapper arapMapper;

    @Autowired
    private ArapDetailMapper arapDetailMapper;

    @Autowired
    private SaleIntentionMapper saleIntentionMapper;

    @Autowired
    private DeliveryReceiptLinkMapper deliveryReceiptLinkMapper;

    @Autowired
    private DeliveryReceiptMaterialService deliveryReceiptMaterialService;

    @Autowired
    private DeliveryReceiptMaterialMapper deliveryReceiptMaterialMapper;

    @Autowired
    private SystemParameterService systemParameterService;

    @Autowired
    private DeliveryReceiptMapper deliveryReceiptMapper;

    @Autowired
    private DeliveryReceiptService deliveryReceiptService;

    @Autowired
    private CompanyDealerService companyDealerService;

    @Autowired
    private PurchaseRequestMapper purchaseRequestMapper;
    @Autowired
    private WarehouseAreaLocationDOMapper warehouseAreaLocationDOMapper;
    @Autowired
    private DepartmentWarehouseRelationService relationService;


    /**
     * 发运交接单发货后过账的公司（主机厂）orgId 参数Type
     */
    private static final String POST_AFTER_DELIVERY_SEND_COM = "DELIVERY_POST_COM";
    /**
     * 发运交接单发货后过账的公司（客户）orgId 参数Type，数据对应company_dealer.dealer_org_id
     */
    private static final String POST_AFTER_DELIVERY_SEND_DEALER = "DELIVERY_POST_DEALER";


    /**
     * 发货通知完成状态：0未开始，1进行中，2已完成
     */
    private static final String DELIVERY_STATUS_UN_START = "0", DELIVERY_STATUS_PROCESSING = "1", DELIVERY_STATUS_FINISH = "2";


    /**
     * 铲运电商的dealer_code
     */
    private static final String CYDS_DEALER_CODE = "176938";
    /**
     * 铲运电商的请求地址
     */
    private static final String CYDS_INTERFACE_ADDR = "http://www.loaderking.com/SHOP/main.action";

    private static void rounding(DeliveryNoteDO entity) {

        if (entity.getTotalDiscountPrice() != null) {
            //取整
            entity.setTotalDiscountPrice(entity.getTotalDiscountPrice().multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP));
        }
        if (entity.getTotalSettlementPrice() != null) {
            //取整
            entity.setTotalSettlementPrice(entity.getTotalSettlementPrice().multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP));
        }

    }

    private static void takeDecimals(DeliveryNoteVO model) {

        if (model.getTotalDiscountPrice() != null) {
            model.setTotalDiscountPrice(model.getTotalDiscountPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP));
        }
        if (model.getTotalSettlementPrice() != null) {
            model.setTotalSettlementPrice(model.getTotalSettlementPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP));
        }

    }

    private static BigDecimal takeDecimals(BigDecimal integer) {
        if (integer == null) {
            return new BigDecimal(0);
        }
        return integer.divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
    }

    private static BigDecimal rounding(BigDecimal decimal) {
        if (decimal == null) {
            return new BigDecimal(0);
        }
        return decimal.multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * @Des needJudgeAudit是否需要判断是否需要审核
     * @Date 2021/4/11 17:50
     * @Author wangzhaoyu
     * @Param [deliveryNoteAddVO, userId, orgId, needJudgeAudit]
     * @Return xcmg.device.infra.ErrorCode
     */
    @Transactional(rollbackFor = Exception.class)
    public synchronized ErrorCode add(DeliveryNoteAddVO deliveryNoteAddVO, String userId, String orgId, boolean needJudgeAudit) throws Exception {
        Date now = new Date();
        DataDictionaryDO delivery = dataDictionaryMapper.itemByCode("WLZT", "0");
        DataDictionaryDO out = dataDictionaryMapper.itemByCode("INOUTSTATE", "0");
        DeliveryNoteVO headerInfo = deliveryNoteAddVO.getHeaderInfo();
        //如果更新的信息中存在尾插金额，则需要判断该发货通知单对应的销售订单创建出来的所有发货通知单的尾插金额之和是否超过销售订单的尾插金额
        BigDecimal cashShortAndOver = headerInfo.getCashShortAndOver();
        String saleNo = headerInfo.getSaleNo();
        if (cashShortAndOver != null && cashShortAndOver.compareTo(BigDecimal.ZERO) > 0 && !StringUtils.isEmpty(saleNo)) {
            //查询非自己的发货通知单的尾差总金额和销售订单的尾差金额
            BigDecimal salIntentionCash = saleIntentionMapper.selectCashShortBySaleNo(saleNo);
            salIntentionCash = salIntentionCash == null ? BigDecimal.ZERO : salIntentionCash;
            BigDecimal hasCreatedCash = deliveryNoteMapper.sumCashAndOverBySaleNo(saleNo);
            hasCreatedCash = hasCreatedCash == null ? BigDecimal.ZERO : hasCreatedCash;
            if (cashShortAndOver.add(hasCreatedCash).subtract(salIntentionCash).compareTo(BigDecimal.ZERO) > 0) {
                return ErrorCode.CashShortAndOverIllege;
            }
        }
        //发货通知单增加
        DeliveryNoteDO deliveryNoteDO = new DeliveryNoteDO();
        BeanUtils.copyProperties(headerInfo, deliveryNoteDO);
        Integer forward = headerInfo.getForward();
        forward = forward == null ? ForwardBarcodeLableEnum.NO_FORWARD_BARCODE.getLable() : forward;
        deliveryNoteDO.setForward(forward);
        deliveryNoteDO.setTotalDiscountPrice(new BigDecimal(0));
        ActionResult<String> textNote = fastGenClient.textGuid();
        if (textNote.getCode() != ErrorCode.Success.getCode()) {
            return ErrorCode.IllegalArument;
        }
        CompanyDealerDO companyInfoVO = companyDealerMapper.itemByOrgId(orgId, headerInfo.getPurchaseOrgId());
        if (companyInfoVO == null) {
            LogHelper.error("企业不存在", ErrorCode.RequestIdError.getCode());
            return ErrorCode.DealerInfoNotExist;
        }
        if (companyInfoVO.getDealerCode() == null) {
            companyInfoVO.setDealerCode(headerInfo.getPurchaseOrgId());
        }
        deliveryNoteDO.setSold(companyInfoVO.getDealerCode());
        deliveryNoteDO.setDelivery(companyInfoVO.getDealerCode());
        //内 部主键
        deliveryNoteDO.setId(textNote.getValue().toString());
        //发货通知单号
        if (StringUtil.isNullOrEmpty(deliveryNoteDO.getDeliveryNo())) {
            deliveryNoteDO.setDeliveryNo(genDocumentService.genDocumentNo(BillDesc.DeliveryNo, orgId));
        }
        //外向发货单号
        deliveryNoteDO.setSapOutNo(genDocumentService.getDeliveryNo());
        deliveryNoteDO.setAgentApplicationNo(genDocumentService.getDocumentNo(BillDesc.AgentApplicationNo));
        deliveryNoteDO.setSaleNo(headerInfo.getSaleNo());
        deliveryNoteDO.setCustomerPurchaseDate(now);
        deliveryNoteDO.setCustomerPurchaseCode(headerInfo.getCustomerPurchaseCode());
        if (delivery.getName() == null) {
            return ErrorCode.IllegalArument;
        } else {
            deliveryNoteDO.setLogState(delivery.getName());
        }
        //新增发货通知单时初始化审核状态，如果是需要审核的则设置为待审核，否则直接为审核通过
        if (needJudgeAudit) {
            boolean needAudit = systemParameterService.getDeliveryNoteAuditSetting(orgId);
            if (needAudit) {
                deliveryNoteDO.setReviewState(DeliveryNoteAuditStatusEnum.AUDIT_WAIT.getAuditStatus());
            } else {
                deliveryNoteDO.setReviewState(DeliveryNoteAuditStatusEnum.AUDIT_PASS.getAuditStatus());
                deliveryNoteDO.setAuditDate(now);
                deliveryNoteDO.setAuditUserId("00001");
                deliveryNoteDO.setAuditUserName("系统自动");
            }
        }
        deliveryNoteDO.setState(0);
        deliveryNoteDO.setTicketState(0);
        deliveryNoteDO.setIsOut("0");
        deliveryNoteDO.setIsReverse(0);
        deliveryNoteDO.setIsPosting(0);
        deliveryNoteDO.setIsPrint(0);
        deliveryNoteDO.setModifyCode(headerInfo.getCreatorId());
        deliveryNoteDO.setModifyDate(now);

        SaleIntentionDO saleIntention = saleIntentionMapper
                .itemByNo(headerInfo.getSaleNo(), orgId);
        if (null != saleIntention) {
            deliveryNoteDO.setCountry(saleIntention.getCountry());
        }
        if (out.getName() == (null)) {
            return ErrorCode.IllegalArument;
        } else {
            deliveryNoteDO.setIsOutDesc(out.getName());
        }
        rounding(deliveryNoteDO);
        //发货通知详情增加
        List<FindMaterialsInfos> infos = new ArrayList<>();
        for (DeliveryNoteDetailVO detail : deliveryNoteAddVO.getMaterialList()) {
            //本次发货数量不能大于剩余数量
            if ((detail.getSendQty().add(detail.getDeliveryQty())).compareTo(detail.getAmountAfterAdjust()) > 0) {
                return ErrorCode.DeliveryNoteQtyError;
            }
            FindMaterialsInfos findMaterialsInfos = new FindMaterialsInfos();
            findMaterialsInfos.setMaterialsNo(detail.getMaterialsNo());
            findMaterialsInfos.setAmount(detail.getDeliveryQty());
            infos.add(findMaterialsInfos);
        }
        FindMaterialsNumParam findMaterialsNumParam = new FindMaterialsNumParam();
        findMaterialsNumParam.setMaterialsNos(infos);
        findMaterialsNumParam.setOrgId(orgId);
        findMaterialsNumParam.setWarehousCode(headerInfo.getOutLocation());
        if (!warehouseInventoryService.findMaterialsNum(findMaterialsNumParam)) {
            return ErrorCode.PartMaterialsNotNumber;
        }
        List<InformVO> informVOS = new ArrayList<>();
        for (DeliveryNoteDetailVO detail : deliveryNoteAddVO.getMaterialList()) {
            DeliveryNoteDetailDO detailDO = new DeliveryNoteDetailDO();
            BeanUtils.copyProperties(detail, detailDO);
            ActionResult<String> textNoteDetail = fastGenClient.textGuid();
            if (textNoteDetail.getCode() != ErrorCode.Success.getCode()) {
                return ErrorCode.IllegalArument;
            }
            detailDO.setId(textNoteDetail.getValue().toString());
            detailDO.setDeliveryNoteNo(deliveryNoteDO.getId());
            detailDO.setCreateCode(deliveryNoteDO.getCreatorId());
            detailDO.setIsDel(false);
            detailDO.setDeliveryQty(detailDO.getDeliveryQty());
            detailDO.setPrice(rounding(detailDO.getPrice()));
            detailDO.setApplyTotalPrice(detailDO.getQty().multiply(detailDO.getPrice()));
            detailDO.setAmountAfterAdjust(detailDO.getAmountAfterAdjust());
            detailDO.setUnitPriceAfterAdjust(rounding(detailDO.getUnitPriceAfterAdjust()));
            detailDO.setTotalPriceAfterAdjust(detailDO.getUnitPriceAfterAdjust().multiply(detailDO.getDeliveryQty()));
            detailDO.setOrgId(deliveryNoteDO.getSupplierOrgId());
            detailDO.setInventoryOutAmount(new BigDecimal(0));
            if (detailDO.getDeliveryDate() == null) {
                detailDO.setDeliveryDate(now);
            }
            deliveryNoteDO.setTotalDiscountPrice(deliveryNoteDO.getTotalDiscountPrice().add(detailDO.getTotalPriceAfterAdjust().setScale(0, BigDecimal.ROUND_HALF_UP)));

            if (detailDO.getDeliveryQty() == null) {
                return ErrorCode.DeliveryNoteDetailQtyDesc;
            } else {
                if (detailDO.getAmountAfterAdjust().compareTo(detailDO.getDeliveryQty()) < 0) {
                    return ErrorCode.DeliveryNoteDetailQty;
                }
            }
            SaleIntentionDetailDO saleIntentionDetailDO = saleIntentionDetailMapper.selectByNo(headerInfo.getSaleNo(), detailDO.getMaterialsNo());
            if (saleIntentionDetailDO == null) {
                return ErrorCode.Failure;
            }
            InformVO informVO = new InformVO();
            informVO.setSaleNo(headerInfo.getSaleNo());
            //订单总数量
            informVO.setAmount(detailDO.getAmountAfterAdjust());
            informVO.setMaterialsNo(detailDO.getMaterialsNo());
            //已发数量(本次发货数量+发运数)
            informVO.setInformedAmount(saleIntentionDetailDO.getInformedAmount().add(detailDO.getDeliveryQty()));
            informVOS.add(informVO);
            if (!String.valueOf(DeliveryStatus.Saved.getCode()).equals(deliveryNoteDO.getStatus())) {
                detailDO.setSendQty(informVO.getInformedAmount());
            }

            validationOutQty(detailDO, informVO);

            deliveryNoteDetailMapper.add(detailDO);
        }
        if (String.valueOf(DeliveryStatus.Saved.getCode()).equals(deliveryNoteDO.getStatus())) {
            deliveryNoteMapper.add(deliveryNoteDO);
        } else {
            deliveryNoteMapper.add(deliveryNoteDO);
            saleIntentionService.updateInformAmount(informVOS, deliveryNoteDO.getSupplierOrgId());
            updateSendQty(informVOS, deliveryNoteDO.getSupplierOrgId());

            //新增发货通知单时新增发货事物单
            headerInfo.setDeliveryNo(deliveryNoteDO.getDeliveryNo());
            headerInfo.setId(deliveryNoteDO.getId());//主键
            warehouseDeliveryService.saveByDeliveryNoteOut(deliveryNoteAddVO, userId, orgId);

            //如果是代理商生成应收记录
            //2019-12-02 主机厂和代理商都从发货通知单新增应收记录
//            CompanyInfoVO infoVO = companyInfoService.info(deliveryNoteDO.getSupplierOrgId());
//            if (infoVO != null && (infoVO.getIsSap() == null || infoVO.getIsSap() == 0)) {
//                this.balanceAdd(deliveryNoteDO);
//            }
            this.balanceAdd(deliveryNoteDO);
        }

        //挖机紧急订单自动生成运单
        deliveryReceiptService.addByDeliveryNote(deliveryNoteDO);
        // 如果是铲运电商的订单，创建发货通知单后通知铲运
        if (CYDS_DEALER_CODE.equals(companyInfoVO.getDealerCode())) {
            sendDeliveryInfo2CYDS(saleIntention, deliveryNoteDO);
        }
        return ErrorCode.Success;
    }


    /**
     * 调用铲运电商提供的接口，将其创建的销售订单状态传回去
     *
     * @param saleIntentionDO
     * @param deliveryNoteDO
     */
    private String sendDeliveryInfo2CYDS(SaleIntentionDO saleIntentionDO,
                                         DeliveryNoteDO deliveryNoteDO) {
        StringBuilder url = new StringBuilder(CYDS_INTERFACE_ADDR);
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            url.append("?orderId=").append(saleIntentionDO.getPurchaseNo());
            url.append("&despatchNo=").append(saleIntentionDO.getPurchaseNo());
            PurchaseRequestDO purchaseRequestDO = purchaseRequestMapper.itemByBillNo(saleIntentionDO.getPurchaseNo());
            if (null != purchaseRequestDO) {
                url.append("&orderPurchchaseDate=").append(sdf.format(purchaseRequestDO.getCreateDate()));
            }
            url.append("&clientName=").append(saleIntentionDO.getPurchaseOrgName());
            url.append("&applyDate=").append(sdf.format(saleIntentionDO.getCreateDate()));
            url.append("&plantName=").append(saleIntentionDO.getSupplierOrgName());
            url.append("&forwardIngType=").append(saleIntentionDO.getDeliverTypeName());
            url.append("&closeType=").append(saleIntentionDO.getSettleTypeName());
            url.append("&consigneeName=").append(deliveryNoteDO.getReceiverName());
            url.append("&consigneeMoblie=").append(deliveryNoteDO.getReceiverPhone());
            url.append("&orderAllPrice=").append(saleIntentionDO.getTotalSettlementPrice());
            url.append("&gatheringPrice=").append(saleIntentionDO.getTotalSettlementPrice());
            url.append("&auditStatus=").append("审核通过");
            url.append("&isValido=").append("是");
            url.append("&deliveryStatus=").append("未出库");
            url.append("&remark=").append(saleIntentionDO.getRemark());
            url.append("&createDate=").append(sdf.format(deliveryNoteDO.getCreateDate()));
            url.append("&createName=").append(saleIntentionDO.getCreateName());
            //url.append("&createDept=").append("");
            url.append("&createCompany=").append(saleIntentionDO.getSupplierOrgName());
            //url.append("&signDate=").append("");
            url.append("&status=").append(saleIntentionDO.getStatusDes());
            HttpRequestUtil.sendSimpleGet(url.toString());
        } catch (Exception e) {
            LogHelper.fatal("sendDeliveryInfo2CYDS is error. url=" + url.toString(), e);
        }
        return StringUtils.EMPTY;
    }

    private void validationOutQty(DeliveryNoteDetailDO detailDO, InformVO informVO) throws Exception {
        //  判断调销售订单实际出库数量与调整后的数量比较，如大于抛异常
        BigDecimal ZERO = new BigDecimal(0);
        String materialsNo = informVO.getMaterialsNo();
        String saleNo = informVO.getSaleNo();
        BigDecimal deliveryQty = detailDO.getDeliveryQty() == null ? ZERO : detailDO.getDeliveryQty();
        BigDecimal amountAfterAdjust = deliveryNoteDetailMapper.getAmountAfterAdjust(saleNo, materialsNo);
        BigDecimal sendQty = deliveryNoteDetailMapper.getSendQty(saleNo, materialsNo);
        BigDecimal actualOutQty = deliveryQty.add(sendQty == null ? ZERO : sendQty);
        if (actualOutQty.compareTo(amountAfterAdjust) > 0) {
            String createdDeliveryNos = deliveryNoteDetailMapper.getCreatedDeliverys(saleNo, materialsNo);
            createdDeliveryNos = StringUtils.isBlank(createdDeliveryNos) ? StringUtils.EMPTY : createdDeliveryNos;
            throw new Exception(
                    "销售单号为: " + saleNo + "的销售订单，零件号为：" + materialsNo
                            + "，实际出库数量大于销售订单调整后的数量，包含该零件的发货通知单：" + createdDeliveryNos);
        }
    }

    public ErrorCode updateSendQty(List<InformVO> informVOList, String orgId) {
        if (ListUtil.isNullOrEmpty(informVOList)) {
            return ErrorCode.IllegalArument;
        }
        for (InformVO infromVO : informVOList) {
            String status = infromVO.getStatus();
            if (StringUtils.isNotBlank(status) && "3".equals(status)) {//防止结单之后删除单据重复扣减
                continue;
            }
            deliveryNoteDetailMapper.updateSendQty(orgId, infromVO.getInformedAmount(), infromVO.getSaleNo(), infromVO.getMaterialsNo());
        }
        return ErrorCode.Success;
    }

    private void balanceAdd(DeliveryNoteDO deliveryNoteDO) throws Exception {
        deliveryNoteDO.setTotalDiscountPrice(deliveryNoteDO.getTotalDiscountPrice().divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP));
        //生成应收记录
        CompanyDealerDO dealerDO = companyDealerMapper.itemByOrgId(deliveryNoteDO.getSupplierOrgId(), deliveryNoteDO.getPurchaseOrgId());
        ArapDO arapDO = arapMapper.selectByAccOrgId(deliveryNoteDO.getSupplierOrgId(), dealerDO.getDealerOrgId(), 0);
        if (arapDO == null) {
            arapDO = new ArapDO();
            arapDO.setId(fastGenClient.textGuid().getValue());
            arapDO.setOrgId(deliveryNoteDO.getSupplierOrgId());
            arapDO.setAccOrgId(dealerDO.getDealerOrgId());
            arapDO.setAccOrgName(dealerDO.getCompanyName());
            arapDO.setDealerCode(dealerDO == null ? "" : dealerDO.getDealerCode());
            arapDO.setArapType(0);
            arapDO.setReceiverPrice(deliveryNoteDO.getTotalDiscountPrice());
            arapDO.setCreateDate(new Date());
            arapMapper.insert(arapDO);
        } else {
            arapDO.setReceiverPrice(arapDO.getReceiverPrice().add(deliveryNoteDO.getTotalDiscountPrice()));
            arapDO.setUpdateDate(new Date());
            arapMapper.update(arapDO);
        }

        ArapDetailDO arapDetailDO = arapDetailMapper.selectByBillNo(deliveryNoteDO.getSupplierOrgId(), deliveryNoteDO.getDeliveryNo());
        if (arapDetailDO == null) {
            arapDetailDO = new ArapDetailDO();
            arapDetailDO.setId(fastGenClient.textGuid().getValue());
            arapDetailDO.setSupplierOrgId(deliveryNoteDO.getSupplierOrgId());
            arapDetailDO.setSupplierOrgName(deliveryNoteDO.getSupplierOrgName());
            arapDetailDO.setPurchaseOrgId(dealerDO.getDealerOrgId());
            arapDetailDO.setPurchaseOrgName(dealerDO.getCompanyName());
            arapDetailDO.setDeliveryOutNo(deliveryNoteDO.getSapOutNo());
            arapDetailDO.setBillId(deliveryNoteDO.getId());
            arapDetailDO.setBillNo(deliveryNoteDO.getDeliveryNo());
            arapDetailDO.setBillDate(deliveryNoteDO.getCreateDate());
            arapDetailDO.setBillSingle(StringUtils.left(deliveryNoteDO.getDeliveryNo(), 4));
            arapDetailDO.setTotalPrice(deliveryNoteDO.getTotalDiscountPrice());
            arapDetailDO.setRemainPrice(deliveryNoteDO.getTotalDiscountPrice());
            arapDetailDO.setCreateDate(new Date());
            arapDetailMapper.insert(arapDetailDO);
        } else {
            arapDetailDO.setTotalPrice(arapDetailDO.getTotalPrice().add(deliveryNoteDO.getTotalDiscountPrice()));
            arapDetailDO.setRemainPrice(arapDetailDO.getTotalPrice().subtract(arapDetailDO.getReceivePrice()));
            arapDetailDO.setUpdateDate(new Date());
            arapDetailMapper.update(arapDetailDO);
        }
    }

    /**
     * 删除发货通知单更新应收信息
     * 删除对应的明细，更新主表数据
     *
     * @param deliveryNoteDO
     */
    private void updateArapInfo(DeliveryNoteDO deliveryNoteDO) {
        String purchaseOrgId = deliveryNoteDO.getPurchaseOrgId();
        CompanyDealerDO companyDealerDO = companyDealerMapper.itemByOrgId(deliveryNoteDO.getSupplierOrgId(), purchaseOrgId);
        if (companyDealerDO == null) {
            return;
        }
        String dealerOrgId = companyDealerDO.getDealerOrgId();
        ArapDO arapDO = arapMapper.selectByAccOrgId(deliveryNoteDO.getSupplierOrgId(), dealerOrgId, 0);
        if (null == arapDO) {
            return;
        }
        ArapDetailDO arapDetailDO = arapDetailMapper.selectByBillNo(deliveryNoteDO.getSupplierOrgId(), deliveryNoteDO.getDeliveryNo());
        if (null == arapDetailDO) {
            return;
        }
        arapDetailMapper.updateDelById(arapDetailDO.getId());
        BigDecimal afterReceiverPrice = arapDO.getReceiverPrice().subtract(
                deliveryNoteDO.getTotalDiscountPrice().divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP));
        if (BigDecimal.ZERO.compareTo(afterReceiverPrice) == 0) {
            arapMapper.deleteByPrimaryKey(arapDO.getId());
        } else {
            arapDO.setOldReceiverPrice(arapDO.getReceiverPrice());
            arapDO.setReceiverPrice(afterReceiverPrice);
            arapDO.setUpdateDate(new Date());
            arapMapper.update(arapDO);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public ErrorCode remove(List<String> ids) {
        List<DeliveryReceiptMaterialVO> receiptMaterialList = new ArrayList<>();
        Set<String> receIds = new HashSet<>();
        for (String id : ids) {

            DeliveryNoteDO deliveryNoteDO = deliveryNoteMapper.item(id);
            List<String> receiptIds = deliveryReceiptLinkMapper.findReceiptIds(id);
            receIds.addAll(receiptIds);
            if ("1".equals(deliveryNoteDO.getStatus())) {//已提交的发后通知单删除时要扣减销售意向已发货数
                List<InformVO> informVOS = new ArrayList<>();
                //存储发货通知单中所有零件，用于后续判断
                List<String> materialsNos = new ArrayList<>();
                for (DeliveryNoteDetailDO noteDetailVO : deliveryNoteDetailMapper.list(id)) {
                    materialsNos.add(noteDetailVO.getMaterialsNo());
                    InformVO informVO = new InformVO();
                    informVO.setSaleNo(deliveryNoteDO.getSaleNo());
                    //订单总数量
                    informVO.setAmount(noteDetailVO.getAmountAfterAdjust());
                    informVO.setMaterialsNo(noteDetailVO.getMaterialsNo());
                    //已发数量(本次发货数量-发运数)
                    informVO.setStatus(noteDetailVO.getStatus());
                    informVO.setInformedAmount(noteDetailVO.getSendQty().subtract(noteDetailVO.getDeliveryQty()));
                    informVOS.add(informVO);

                    if (!ListUtil.isNullOrEmpty(receiptIds)) {
                        for (String receiptId : receiptIds) {
                            DeliveryReceiptMaterialVO receiptMaterialDO = new DeliveryReceiptMaterialVO();
                            receiptMaterialDO.setDeliveryReceiptId(receiptId);
                            receiptMaterialDO.setMaterialsNo(noteDetailVO.getMaterialsNo());
                            receiptMaterialDO.setQty(noteDetailVO.getDeliveryQty());
                            receiptMaterialDO.setUpdateType(0);
                            receiptMaterialList.add(receiptMaterialDO);
                        }
                    }
                }

                if (!ListUtil.isNullOrEmpty(receiptIds)) {
                    for (String receiptId : receiptIds) {
                        deliveryReceiptLinkMapper.deleteItem(receiptId, id);
                    }
                }
//                saleIntentionService.updateInformAmount(informVOS, deliveryNoteDO.getSupplierOrgId());
                //先删除，再统计发货通知数量，确保前面操作的数据对本次操作可见
//                TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
//                    @Override
//                    public void afterCommit() {
//
//                    }
//                });
                deliveryNoteMapper.deleteByPrimaryKey(id);
                updateSaleIntention(deliveryNoteDO.getSaleNo(), deliveryNoteDO.getSupplierOrgId(), materialsNos);
                updateSendQty(informVOS, deliveryNoteDO.getSupplierOrgId());

            } else {
                deliveryNoteMapper.deleteByPrimaryKey(id);
            }


            deliveryNoteDetailMapper.delete(id);
            warehouseDeliveryService.removeByBusinessOrders(Arrays.asList(deliveryNoteDO.getDeliveryNo()), deliveryNoteDO.getSupplierOrgId());

            // 2019-12-03 更新应收数据
            updateArapInfo(deliveryNoteDO);
        }
        //更新发运交接单
        deliveryReceiptMaterialService
                .updateByAdjust(new ArrayList<>(receIds), receiptMaterialList);

        return ErrorCode.Success;
    }

    /**
     * 更新销售意向相关字段
     */
    public void updateSaleIntention(String saleNo, String orgId, List<String> deliveryMaterialsNos) {
        SaleIntentionDO saleIntention = saleIntentionMapper.itemByNo(saleNo, orgId);
        if (null == saleIntention) {
            return;
        }
        List<SaleIntentionDetailDO> detailDOS = saleIntentionDetailMapper.list(saleIntention.getId());
        if (CollectionUtils.isEmpty(detailDOS)) {
            return;
        }

        // 尚未创建发货通知单的零件数
        int unstartQty = 0;
        // 已创建完成发货通知单的零件数
        int endQty = 0;
        for (SaleIntentionDetailDO detailDO : detailDOS) {
            BigDecimal deliveryQty = countDeliveryQty(saleNo, detailDO.getMaterialsNo());
            // 只更新此次删除的发货通知单对应的零件的已通知数
            if (deliveryMaterialsNos.contains(detailDO.getMaterialsNo())) {
                detailDO.setInformedAmount(deliveryQty);
                saleIntentionDetailMapper.update(detailDO);
            }
            if (deliveryQty.compareTo(BigDecimal.ZERO) == 0) {
                unstartQty++;
                continue;
            }
            if (deliveryQty.compareTo(detailDO.getAmountAfterAdjust()) == 0) {
                endQty++;
            }
        }

        saleIntention.setDeliverStatus(getStatusByDeliveryQty(unstartQty, endQty, detailDOS.size()));
        saleIntentionMapper.update(saleIntention);
    }

    private String getStatusByDeliveryQty(int unstartQty, int endQty, int totalSize) {
        if (unstartQty == totalSize) {
            return DELIVERY_STATUS_UN_START;
        }
        if (endQty == totalSize) {
            return DELIVERY_STATUS_FINISH;
        }
        return DELIVERY_STATUS_PROCESSING;
    }

    private BigDecimal countDeliveryQty(String saleNo, String materialsNo) {
        BigDecimal deliveryQty = deliveryNoteDetailMapper.countDeliveryQty(saleNo, materialsNo);
        return null == deliveryQty ? BigDecimal.ZERO : deliveryQty;
    }


    @Transactional(rollbackFor = Exception.class)
    public ErrorCode adjust(DeliveryNoteAddVO deliveryNoteAddVO, String orgId) throws Exception {
        DeliveryNoteDO deliveryNoteDO = deliveryNoteMapper.item(deliveryNoteAddVO.getHeaderInfo().getId());
        if (deliveryNoteDO == null) {
            return ErrorCode.DeliveryNoteIdDuplicated;
        }
        //如果更新的信息中存在尾插金额，则需要判断该发货通知单对应的销售订单创建出来的所有发货通知单的尾插金额之和是否超过销售订单的尾插金额
        BigDecimal cashShortAndOver = deliveryNoteAddVO.getHeaderInfo().getCashShortAndOver();
        if (deliveryNoteDO != null && cashShortAndOver != null && cashShortAndOver.compareTo(BigDecimal.ZERO) > 0) {
            String saleNo = deliveryNoteDO.getSaleNo();
            if (!StringUtils.isEmpty(saleNo)) {//查询非自己的发货通知单的尾差总金额和销售订单的尾差金额
                BigDecimal salIntentionCash = saleIntentionMapper.selectCashShortBySaleNo(saleNo);
                salIntentionCash = salIntentionCash == null ? BigDecimal.ZERO : salIntentionCash;
                BigDecimal hasCreatedCash = deliveryNoteMapper.sumCashAndOverBySaleNoRemove(saleNo, deliveryNoteDO.getId());
                hasCreatedCash = hasCreatedCash == null ? BigDecimal.ZERO : hasCreatedCash;
                if (cashShortAndOver.add(hasCreatedCash).subtract(salIntentionCash).compareTo(BigDecimal.ZERO) > 0) {
                    return ErrorCode.CashShortAndOverIllege;
                }
            }
        }
        String addressDB = deliveryNoteDO.getAddress();
        if (!"0".equals(deliveryNoteDO.getIsOut()) && !"1".equals(deliveryNoteDO.getIsOut())) {
            return ErrorCode.DeliveryNoteUpdateError;
        }
        if (!deliveryNoteDO.getIsReturn().equals(0)) {
            return ErrorCode.DeliveryNoteUpdateError;
        }
        if (!deliveryNoteDO.getIsReverse().equals(0) && !deliveryNoteDO.getIsReverse().equals(3)) {
            return ErrorCode.DeliveryNoteUpdateError;
        }
        deliveryNoteDO.setDistributionChannelId(deliveryNoteAddVO.getHeaderInfo().getDistributionChannelId());
        deliveryNoteDO.setDistributionChannelName(deliveryNoteAddVO.getHeaderInfo().getDistributionChannelName());
        deliveryNoteDO.setCustomerPurchaseCode(deliveryNoteAddVO.getHeaderInfo().getCustomerPurchaseCode());
        deliveryNoteDO.setPayConditionId(deliveryNoteAddVO.getHeaderInfo().getPayConditionId());
        deliveryNoteDO.setPayConditionName(deliveryNoteAddVO.getHeaderInfo().getPayConditionName());
        deliveryNoteDO.setOrderType(deliveryNoteAddVO.getHeaderInfo().getOrderType());
        deliveryNoteDO.setDeliveryTypeId(deliveryNoteAddVO.getHeaderInfo().getDeliveryTypeId());
        deliveryNoteDO.setDeliveryTypeName(deliveryNoteAddVO.getHeaderInfo().getDeliveryTypeName());
        deliveryNoteDO.setSettleTypeId(deliveryNoteAddVO.getHeaderInfo().getSettleTypeId());
        deliveryNoteDO.setSettleTypeName(deliveryNoteAddVO.getHeaderInfo().getSettleTypeName());
        deliveryNoteDO.setReceiverName(deliveryNoteAddVO.getHeaderInfo().getReceiverName());
        deliveryNoteDO.setReceiverPhone(deliveryNoteAddVO.getHeaderInfo().getReceiverPhone());
        deliveryNoteDO.setReceiverFax(deliveryNoteAddVO.getHeaderInfo().getReceiverFax());
        deliveryNoteDO.setCashShortAndOver(deliveryNoteAddVO.getHeaderInfo().getCashShortAndOver());
        if (!addressDB.equals(deliveryNoteAddVO.getHeaderInfo().getAddress())) {
            deliveryNoteDO.setAddressCode(StringUtils.EMPTY);
        }
        deliveryNoteDO.setAddress(deliveryNoteAddVO.getHeaderInfo().getAddress());
        deliveryNoteDO.setNote(deliveryNoteAddVO.getHeaderInfo().getNote());
        deliveryNoteDO.setSendTypeChildId(deliveryNoteAddVO.getHeaderInfo().getSendTypeChildId());
        deliveryNoteDO.setSendTypeChildName(deliveryNoteAddVO.getHeaderInfo().getSendTypeChildName());

        List<FindMaterialsInfos> infos = new ArrayList<>();
        for (DeliveryNoteDetailVO detailVO : deliveryNoteAddVO.getMaterialList()) {
            if (Integer.parseInt(detailVO.getStatus()) <= 1) {
                FindMaterialsInfos findMaterialsInfos = new FindMaterialsInfos();
                findMaterialsInfos.setMaterialsNo(detailVO.getMaterialsNo());
                findMaterialsInfos.setAmount(detailVO.getDeliveryQty().subtract(detailVO.getInventoryOutAmount()));
                infos.add(findMaterialsInfos);
            }
        }
        FindMaterialsNumParam findMaterialsNumParam = new FindMaterialsNumParam();
        findMaterialsNumParam.setMaterialsNos(infos);
        findMaterialsNumParam.setOrgId(orgId);
        findMaterialsNumParam.setBusinessOrder(deliveryNoteDO.getDeliveryNo());
        findMaterialsNumParam.setWarehousCode(deliveryNoteAddVO.getHeaderInfo().getOutLocation());
        if (!warehouseInventoryService.findMaterialsNum(findMaterialsNumParam)) {
            return ErrorCode.PartMaterialsNotNumber;
        }
        //获取发货通知单对应的销售订单详情信息
        Map<String, SaleIntentionDetailDO> intentionDetailMap = getIntentionDetailMap(deliveryNoteDO);
        List<DeliveryNoteDetailDO> detailVOS = deliveryNoteDetailMapper.list(deliveryNoteDO.getId());//单据的所有零件
        BigDecimal total = BigDecimal.ZERO;
        List<String> receiptIds = deliveryReceiptLinkMapper.findReceiptIds(deliveryNoteDO.getId());
        List<DeliveryReceiptMaterialVO> receiptMaterialVOList = new ArrayList<>();
        for (DeliveryNoteDetailVO detailVO : deliveryNoteAddVO.getMaterialList()) {
            DeliveryNoteDetailDO detailDO = new DeliveryNoteDetailDO();
            BeanUtils.copyProperties(detailVO, detailDO);
            if (detailVOS.contains(detailDO)) {
                detailVOS.remove(detailDO);//去掉需要编辑的零件，留下的是需要删除的零件
            }
            DeliveryNoteDetailDO deliveryNoteDetailDO = deliveryNoteDetailMapper.selectByPrimaryKey(detailVO.getId());
            if (deliveryNoteDetailDO == null) {
                continue;
            }
            if (!"0".equals(deliveryNoteDetailDO.getStatus()) && !"1".equals(deliveryNoteDetailDO.getStatus())) {
                total = total.add(deliveryNoteDetailDO.getTotalPriceAfterAdjust().setScale(0, BigDecimal.ROUND_HALF_UP));
                continue;
            }
            String materialsNo = detailVO.getMaterialsNo();
            BigDecimal oldQty = deliveryNoteDetailDO.getDeliveryQty();
            BigDecimal sendQty = deliveryNoteDetailDO.getSendQty().subtract(deliveryNoteDetailDO.getDeliveryQty());
            BigDecimal temp = detailVO.getDeliveryQty().add(sendQty);
            SaleIntentionDetailDO intentionDetail = intentionDetailMap.get(materialsNo);
            BigDecimal amountAfterAdjust = intentionDetail == null ? BigDecimal.ZERO :
                    intentionDetail.getAmountAfterAdjust() == null ? BigDecimal.ZERO : intentionDetail.getAmountAfterAdjust();
            if (temp.compareTo(amountAfterAdjust) > 0) {
                total = total.add(deliveryNoteDetailDO.getTotalPriceAfterAdjust().setScale(0, BigDecimal.ROUND_HALF_UP));
                continue;
            }
            deliveryNoteDetailDO.setSendQty(sendQty.add(detailVO.getDeliveryQty()));
            deliveryNoteDetailDO.setDeliveryQty(detailVO.getDeliveryQty());
            BigDecimal smallTotal = detailVO.getDeliveryQty().multiply(detailVO.getUnitPriceAfterAdjust().multiply(new BigDecimal("100")));
            total = total.add(smallTotal.setScale(0, BigDecimal.ROUND_HALF_UP));
            deliveryNoteDetailDO.setTotalPriceAfterAdjust(smallTotal);
            ErrorCode errorCode = warehouseDeliveryService.updateDetailState(deliveryNoteDO.getDeliveryNo(),
                    deliveryNoteDetailDO.getMaterialsNo(), deliveryNoteDetailDO.getDeliveryQty(), Integer.parseInt(deliveryNoteDetailDO.getStatus()), deliveryNoteDO.getSupplierOrgId());
            if (errorCode.getCode() != 0) {
                throw new Exception("更新出库事务单记录失败");
            }
            deliveryNoteDetailMapper.update(deliveryNoteDetailDO);
            List<InformVO> informVOS = new ArrayList<>();
            InformVO informVO = new InformVO();
            informVO.setSaleNo(deliveryNoteDO.getSaleNo());
            informVO.setAmount(deliveryNoteDetailDO.getAmountAfterAdjust());
            informVO.setMaterialsNo(deliveryNoteDetailDO.getMaterialsNo());
            informVO.setInformedAmount(deliveryNoteDetailDO.getSendQty());
            informVOS.add(informVO);
            saleIntentionService.updateInformAmount(informVOS, deliveryNoteDO.getSupplierOrgId());
            updateSendQty(informVOS, deliveryNoteDO.getSupplierOrgId());

            for (String receiptId : receiptIds) {
                DeliveryReceiptMaterialVO receiptMaterialVO = new DeliveryReceiptMaterialVO();
                receiptMaterialVO.setMaterialsNo(deliveryNoteDetailDO.getMaterialsNo());
                receiptMaterialVO.setOldQty(oldQty);
                receiptMaterialVO.setQty(deliveryNoteDetailDO.getDeliveryQty());
                receiptMaterialVO.setDeliveryReceiptId(receiptId);
                receiptMaterialVO.setUpdateType(1);
                receiptMaterialVOList.add(receiptMaterialVO);
            }
        }
        for (DeliveryNoteDetailDO deliveryNoteDetailDO : detailVOS) {
            if (!"0".equals(deliveryNoteDetailDO.getStatus())) {
                continue;
            }
            if (deliveryNoteDetailDO.getMaterialsNo().isEmpty() || deliveryNoteDetailDO.getOrgId().isEmpty()) {
                continue;
            }
            warehouseDeliveryDetailMapper.remove(deliveryNoteDO.getDeliveryNo(), deliveryNoteDetailDO.getOrgId(), deliveryNoteDetailDO.getMaterialsNo());
            DeliveryNoteDetailDO noteDetailDO = deliveryNoteDetailMapper.selectByPrimaryKey(deliveryNoteDetailDO.getId());
            if (noteDetailDO == null) {
                continue;
            }
            if (!"0".equals(noteDetailDO.getStatus()) && !"1".equals(noteDetailDO.getStatus())) {
                continue;
            }

            BigDecimal sendQty = deliveryNoteDetailDO.getSendQty();
            if ((sendQty.compareTo(deliveryNoteDetailDO.getAmountAfterAdjust()) > 0)) {
                continue;
            }
            deliveryNoteDetailDO.setSendQty(deliveryNoteDetailDO.getSendQty());
            deliveryNoteDetailDO.setDeliveryQty(deliveryNoteDetailDO.getDeliveryQty());

            List<InformVO> informVOSS = new ArrayList<>();
            InformVO informVOS = new InformVO();
            informVOS.setSaleNo(deliveryNoteDO.getSaleNo());
            informVOS.setAmount(deliveryNoteDetailDO.getAmountAfterAdjust());
            informVOS.setMaterialsNo(deliveryNoteDetailDO.getMaterialsNo());
            informVOS.setInformedAmount(sendQty.subtract(deliveryNoteDetailDO.getDeliveryQty()));
            informVOSS.add(informVOS);
            saleIntentionService.updateInformAmount(informVOSS, deliveryNoteDO.getSupplierOrgId());
            deliveryNoteDetailMapper.remove(deliveryNoteDetailDO.getId());

            updateSendQty(informVOSS, deliveryNoteDO.getSupplierOrgId());

            for (String receiptId : receiptIds) {
                DeliveryReceiptMaterialVO receiptMaterialVO = new DeliveryReceiptMaterialVO();
                receiptMaterialVO.setMaterialsNo(deliveryNoteDetailDO.getMaterialsNo());
                receiptMaterialVO.setQty(deliveryNoteDetailDO.getDeliveryQty());
                receiptMaterialVO.setDeliveryReceiptId(receiptId);
                receiptMaterialVO.setUpdateType(0);
                receiptMaterialVOList.add(receiptMaterialVO);
            }
        }
        deliveryNoteDO.setTotalDiscountPrice(total);
        deliveryNoteDO.setIsOut(deliveryNoteMapper.findOutStatus(deliveryNoteDO.getId()) + "");

        deliveryNoteDO.setIsOutDesc(DeliveryNoteOutStatusEnum.getDescByStatus(deliveryNoteDO.getIsOut()));
        // 如果是需要审核的公司，在进行调整时需要设置单据的审核状态为带审核
        resetDeliveryNoteReviewState(orgId, deliveryNoteDO);
        deliveryNoteMapper.update4Adjust(deliveryNoteDO);

        //更新发运交接单
        deliveryReceiptMaterialService.updateByAdjust(receiptIds, receiptMaterialVOList);
        //更新代理商预收金额
        updateAgentReceivableAmount(orgId, deliveryNoteDO);
        return ErrorCode.Success;
    }

    /**
     * @Des 如果公司设置为发货通知单需要审核，并且调整的时候单据的内容发生了变化则重置发货通知单的审核状态的待审核，并重置审核信息
     * @Date 2021/4/13 9:30
     * @Author wangzhaoyu
     * @Param [orgId:公司
     * oldDeliveryNoteDO ： 数据库中的发货通知单信息]
     * @Return void
     */
    private void resetDeliveryNoteReviewState(String orgId, DeliveryNoteDO oldDeliveryNoteDO) {
        // 如果审核已经通过了，再调整的时候审核状态不修改
        Integer reviewState = oldDeliveryNoteDO.getReviewState();
        if (reviewState != null && reviewState.compareTo(DeliveryNoteAuditStatusEnum.AUDIT_PASS.getAuditStatus()) == 0) {
            return;
        }
        // 如果审核状态时拒绝的，查看公司是否需要审核步骤，如果需要则重置审核状态为待审核
        if (reviewState != null && reviewState.compareTo(DeliveryNoteAuditStatusEnum.AUDIT_REJECT.getAuditStatus()) == 0) {
            boolean deliveryNoteAuditSetting = systemParameterService.getDeliveryNoteAuditSetting(orgId);
            if (deliveryNoteAuditSetting) {
                oldDeliveryNoteDO.setReviewState(DeliveryNoteAuditStatusEnum.AUDIT_WAIT.getAuditStatus());
                oldDeliveryNoteDO.setAuditUserName(null);
                oldDeliveryNoteDO.setAuditUserId(null);
                oldDeliveryNoteDO.setAuditRemark(null);
                oldDeliveryNoteDO.setAuditDate(null);
            }
        }
    }

    //更新代理商预收金额
    private void updateAgentReceivableAmount(String orgId, DeliveryNoteDO deliveryNoteDO) throws Exception {

        /*CompanyInfoVO info = companyInfoService.info(orgId);
        if (null == info || null == info.getIsSap() || 0 != info.getIsSap()) {
            return;
        }*/
        //before 代理商更新调整后应收款金额
        //after 2019-12-03 主机厂和代理商都需要调整金额
        List<DeliveryNoteDetailDO> list = deliveryNoteDetailMapper.list(deliveryNoteDO.getId());
        BigDecimal totalPrice = BigDecimal.ZERO;
        if (ListUtil.isNullOrEmpty(list)) {
            return;
        }
        ArapDetailDO arapDetailDO = arapDetailMapper.selectByBillNo(orgId, deliveryNoteDO.getDeliveryNo());
        if (null == arapDetailDO) {
            return;
        }

        for (DeliveryNoteDetailDO detailDO : list) {
            if ("3".equals(detailDO.getStatus())) {
                totalPrice = totalPrice.add(detailDO.getInventoryOutAmount().multiply(detailDO.getUnitPriceAfterAdjust()));
            } else {
                totalPrice = totalPrice.add(detailDO.getDeliveryQty().multiply(detailDO.getUnitPriceAfterAdjust()));
            }
        }

        DeliveryNoteDO updateDeliveryNoteDO = new DeliveryNoteDO();
        updateDeliveryNoteDO.setTotalDiscountPrice(totalPrice);
        updateDeliveryNoteDO.setId(deliveryNoteDO.getId());
        totalPrice = totalPrice.divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
        if (totalPrice.compareTo(BigDecimal.ZERO) == 0) {
            updateDeliveryNoteDO.setCheckState(2);
        } else {
            updateDeliveryNoteDO.setCheckState(0);
        }
        deliveryNoteMapper.update(updateDeliveryNoteDO);

        BigDecimal oldRemainPrice = arapDetailDO.getRemainPrice();
        ArapDetailDO updateArapDetailDO = new ArapDetailDO();
        updateArapDetailDO.setRemainPrice(totalPrice);
        if (totalPrice.compareTo(BigDecimal.ZERO) == 0) {
            updateArapDetailDO.setIsSettle(1);
        } else {
            updateArapDetailDO.setIsSettle(0);
        }
        updateArapDetailDO.setTotalPrice(totalPrice);
        updateArapDetailDO.setId(arapDetailDO.getId());
        int updateCount = arapDetailMapper.update(updateArapDetailDO);
        if (updateCount <= 0) {
            throw new Exception("扣减应收款详情金额失败");
        }

        //扣减应收主表欠款金额
        ArapDO updateRecord = new ArapDO();
        ArapDO arapDO = arapMapper.selectByAccOrgId(orgId, arapDetailDO.getPurchaseOrgId(), 0);
        updateRecord.setOldReceiverPrice(arapDO.getReceiverPrice());
        updateRecord.setReceiverPrice(arapDO.getReceiverPrice().subtract(oldRemainPrice).add(totalPrice));
        updateRecord.setId(arapDO.getId());
        int updateArapCount = arapMapper.updateSelective(updateRecord);
        if (updateArapCount <= 0) {
            throw new Exception("扣减应收款欠款金额失败");
        }


    }

    @Transactional(rollbackFor = Exception.class)
    public synchronized ErrorCode update(DeliveryNoteAddVO deliveryNoteAddVO, String userId, String orgId) throws Exception {
        DeliveryNoteVO headerInfo = deliveryNoteAddVO.getHeaderInfo();
        CompanyDealerDO companyInfoVO = companyDealerMapper.itemByOrgId(orgId, headerInfo.getPurchaseOrgId());
        if (companyInfoVO == null) {
            LogHelper.error("企业不存在", ErrorCode.RequestIdError.getCode());
            return ErrorCode.ImportExcelNoData;
        }

        DeliveryNoteDO deliveryNoteDB = deliveryNoteMapper.item(headerInfo.getId());
        //如果更新的信息中存在尾插金额，则需要判断该发货通知单对应的销售订单创建出来的所有发货通知单的尾插金额之和是否超过销售订单的尾插金额
        BigDecimal cashShortAndOver = headerInfo.getCashShortAndOver();
        if (deliveryNoteDB != null && cashShortAndOver != null && cashShortAndOver.compareTo(BigDecimal.ZERO) > 0) {
            String saleNo = deliveryNoteDB.getSaleNo();
            if (!StringUtils.isEmpty(saleNo)) {//查询非自己的发货通知单的尾差总金额和销售订单的尾差金额
                BigDecimal salIntentionCash = saleIntentionMapper.selectCashShortBySaleNo(saleNo);
                salIntentionCash = salIntentionCash == null ? BigDecimal.ZERO : salIntentionCash;
                BigDecimal hasCreatedCash = deliveryNoteMapper.sumCashAndOverBySaleNoRemove(saleNo, deliveryNoteDB.getId());
                hasCreatedCash = hasCreatedCash == null ? BigDecimal.ZERO : hasCreatedCash;
                if (cashShortAndOver.add(hasCreatedCash).subtract(salIntentionCash).compareTo(BigDecimal.ZERO) > 0) {
                    return ErrorCode.CashShortAndOverIllege;
                }
            }
        }

        //发货通知单更新
        DeliveryNoteDO deliveryNoteDO = new DeliveryNoteDO();
        headerInfo.setTotalDiscountPrice(rounding(headerInfo.getTotalDiscountPrice()));
        headerInfo.setTotalSettlementPrice(rounding(headerInfo.getTotalSettlementPrice()));
        BeanUtils.copyProperties(headerInfo, deliveryNoteDO);
        deliveryNoteDO.setNote(headerInfo.getNote());
        deliveryNoteDO.setSold(companyInfoVO.getDealerCode());
        deliveryNoteDO.setDelivery(companyInfoVO.getDealerCode());
        deliveryNoteDO.setTotalDiscountPrice(new BigDecimal(0));
        deliveryNoteDO.setTotalSettlementPrice(new BigDecimal(0));
        deliveryNoteDO.setLogState(headerInfo.getLogState());
        deliveryNoteDO.setIsOut(headerInfo.getOut());
        deliveryNoteDO.setPurchaseLevelName(headerInfo.getPurchaseLevelName());
        deliveryNoteDO.setCountry(headerInfo.getCountry());
        Integer forward = headerInfo.getForward();
        forward = forward == null ? ForwardBarcodeLableEnum.NO_FORWARD_BARCODE.getLable() : forward;
        deliveryNoteDO.setForward(forward);
        //发货通知详情更新
        //先判断是否符合条件，再删除
        List<FindMaterialsInfos> infos = new ArrayList<>();
        for (DeliveryNoteDetailVO detailVO : deliveryNoteAddVO.getMaterialList()) {

            if (detailVO.getDeliveryQty() == null) {
                return ErrorCode.DeliveryNoteDetailQtyDesc;
            } else if (detailVO.getDeliveryQty().add(detailVO.getSendQty()).compareTo(detailVO.getAmountAfterAdjust()) > 0) {
                return ErrorCode.DeliveryNoteQty;
            }
            if (Integer.parseInt(detailVO.getStatus()) <= 1) {
                FindMaterialsInfos findMaterialsInfos = new FindMaterialsInfos();
                findMaterialsInfos.setMaterialsNo(detailVO.getMaterialsNo());
                findMaterialsInfos.setAmount(detailVO.getDeliveryQty().subtract(detailVO.getInventoryOutAmount()));
                infos.add(findMaterialsInfos);
            }
        }
        FindMaterialsNumParam findMaterialsNumParam = new FindMaterialsNumParam();
        findMaterialsNumParam.setMaterialsNos(infos);
        findMaterialsNumParam.setOrgId(orgId);
        findMaterialsNumParam.setBusinessOrder(deliveryNoteDO.getDeliveryNo());
        findMaterialsNumParam.setWarehousCode(headerInfo.getOutLocation());
        if (!warehouseInventoryService.findMaterialsNum(findMaterialsNumParam)) {
            return ErrorCode.PartMaterialsNotNumber;
        }

        deliveryNoteDetailMapper.deleteReal(headerInfo.getId());
        List<DeliveryNoteDetailDO> noteDetailDOList = new ArrayList<DeliveryNoteDetailDO>();
        List<InformVO> informVOS = new ArrayList<>();
        for (DeliveryNoteDetailVO detailVO : deliveryNoteAddVO.getMaterialList()) {
            ActionResult<String> textResult = fastGenClient.textGuid();
            if (textResult.getCode() != ErrorCode.Success.getCode()) {
                return ErrorCode.IllegalArument;
            }
            DeliveryNoteDetailDO detailDO = new DeliveryNoteDetailDO();
            BeanUtils.copyProperties(detailVO, detailDO);
            detailDO.setId(textResult.getValue().toString());
            detailDO.setDeliveryNoteNo(deliveryNoteDO.getId());
            detailDO.setIsDel(false);
            detailDO.setRemark(detailDO.getRemark());
            detailDO.setPrice(rounding(detailDO.getPrice()));
            detailDO.setDeliveryQty(detailDO.getDeliveryQty());
            //            detailDO.setSendNumber(detailDO.getDeliveryQty().intValue());
            detailDO.setApplyTotalPrice(detailDO.getQty().multiply(detailDO.getPrice()));
            detailDO.setPriceSchemeId(detailVO.getPriceSchemeId());
            detailDO.setPriceSchemeName(detailVO.getPriceSchemeName());
            detailDO.setAmountAfterAdjust(detailDO.getAmountAfterAdjust());
            detailDO.setUnitPriceAfterAdjust(rounding(detailDO.getUnitPriceAfterAdjust()));
            detailDO.setTotalPriceAfterAdjust(detailDO.getDeliveryQty().multiply(detailDO.getUnitPriceAfterAdjust()));
            detailDO.setOrgId(deliveryNoteDO.getSupplierOrgId());
            detailDO.setInventoryOutAmount(new BigDecimal(0));

            SaleIntentionDetailDO saleIntentionDetailDO = saleIntentionDetailMapper.selectByNo(headerInfo.getSaleNo(), detailDO.getMaterialsNo());
            if (saleIntentionDetailDO == null) {
                return ErrorCode.Failure;
            }
            InformVO informVO = new InformVO();
            informVO.setSaleNo(headerInfo.getSaleNo());
            //订单总数量
            informVO.setAmount(detailDO.getAmountAfterAdjust());
            informVO.setMaterialsNo(detailDO.getMaterialsNo());
            //已发数量(本次发货数量+发运数)
            informVO.setInformedAmount(saleIntentionDetailDO.getInformedAmount().add(detailDO.getDeliveryQty()));
            informVOS.add(informVO);
            if (!String.valueOf(DeliveryStatus.Saved.getCode()).equals(deliveryNoteDO.getStatus())) {
                detailDO.setSendQty(informVO.getInformedAmount());
            }

            validationOutQty(detailDO, informVO);

            deliveryNoteDetailMapper.add(detailDO);
            deliveryNoteDO.setTotalSettlementPrice(deliveryNoteDO.getTotalSettlementPrice().add(detailDO.getApplyTotalPrice().setScale(0, BigDecimal.ROUND_HALF_UP)));
            deliveryNoteDO.setTotalDiscountPrice(deliveryNoteDO.getTotalDiscountPrice().add(detailDO.getTotalPriceAfterAdjust().setScale(0, BigDecimal.ROUND_HALF_UP)));

            noteDetailDOList.add(detailDO);
        }

        if (!deliveryNoteDB.getAddress().equals(headerInfo.getAddress())) {
            deliveryNoteDO.setAddressCode(StringUtils.EMPTY);
        }

        if (String.valueOf(DeliveryStatus.Saved.getCode()).equals(deliveryNoteDO.getStatus())) {
            deliveryNoteMapper.update(deliveryNoteDO);
        } else {
            deliveryNoteMapper.update(deliveryNoteDO);
            saleIntentionService.updateInformAmount(informVOS, deliveryNoteDO.getSupplierOrgId());
            updateSendQty(informVOS, deliveryNoteDO.getSupplierOrgId());

            //新增发货通知单时新增发货事物单
            warehouseDeliveryService.saveByDeliveryNoteOut(deliveryNoteAddVO, userId, orgId);

            //如果是代理商生成应收记录
            //2019-12-02 主机厂和代理商都从发货通知单新增应收记录
//            CompanyInfoVO infoVO = companyInfoService.info(deliveryNoteDO.getSupplierOrgId());
//            if (infoVO != null && (infoVO.getIsSap() == null || infoVO.getIsSap() == 0)) {
//                this.balanceAdd(deliveryNoteDO);
//            }
            this.balanceAdd(deliveryNoteDO);
        }

        //挖机紧急订单自动生成运单
        deliveryReceiptService.addByDeliveryNote(deliveryNoteDO);
        return ErrorCode.Success;
    }

    public PageCommonVO list(SearchCommonVO<DeliveryNoteVO> condition, String departmentId, String orgId) {
        PageCommonVO result = new PageCommonVO();
        WareHousePermission wareHousePermission = relationService.hasMajorWareHousePermission(orgId, departmentId);
        if (!wareHousePermission.isHasPermission()) {
            result.setPageInfo(new PageInfo(new ArrayList()));
            result.setPageInfoList(new ArrayList<>());
            return result;
        } else {
            condition.getFilters().setWarehousePermitList(wareHousePermission.getPermissionWarehouses());
        }
        condition.getFilters().setBillNosList(xcmg.device.infra.StringUtil.splitList(condition.getFilters().getBillNos()));
        String purchaseNames = condition.getFilters().getPurchaseNames();
        if (StringUtils.isNotEmpty(purchaseNames)) {
            List<String> purchaseNamesList = companyDealerService.listFullNamesByShortName(orgId, purchaseNames);
            if (CollectionUtils.isEmpty(purchaseNamesList)) {
                PageCommonVO pageCommonVO = new PageCommonVO();
                pageCommonVO.setPageInfo(new PageInfo(Collections.EMPTY_LIST));
                pageCommonVO.setPageInfoList(Collections.EMPTY_LIST);
                return pageCommonVO;
            } else {
                condition.getFilters().setPurchaseNamesList(purchaseNamesList);
            }
        }
        PageHelperPlus.orderBy("create_date desc");
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        List<DeliveryNoteDO> doList = deliveryNoteMapper.list(condition.getFilters());
        List<DeliveryNoteVO> voList = new ArrayList<>();
        for (DeliveryNoteDO entity : doList) {
            DeliveryNoteVO model = new DeliveryNoteVO();
            BeanUtils.copyProperties(entity, model);
            takeDecimals(model);
            //需求http://10.90.1.198/zentao/story-view-2907.html
            // 要求列表显示总价，取值跟详情中的表头中总价一致，但是详情中的总价就是直接取得totalDiscountPrice，这里对totalDiscountPrice还有个去掉已收款的计算，不知道原来需求是什么，现在新加一个字段totalPrice当作总价传给前端
            model.setTotalPrice(model.getTotalDiscountPrice());

            getTotalDiscountPrice(condition.getFilters().getSupplierOrgId(), model);
            voList.add(model);
        }
        result.setPageInfo(new PageInfo(doList));
        result.setPageInfoList(voList);
        return result;
    }

    //获取应收款金额
    private void getTotalDiscountPrice(String orgId, DeliveryNoteVO model) {
        BigDecimal totalDiscountPrice = model.getTotalDiscountPrice();
        ArapDetailDO arapDetailDO = arapDetailMapper.selectByBillNo(orgId, model.getDeliveryNo());
        if (null != arapDetailDO) {
            BigDecimal receivePrice = arapDetailDO.getReceivePrice();
            totalDiscountPrice = totalDiscountPrice.subtract(receivePrice == null ? BigDecimal.ZERO : receivePrice);
        }
        model.setTotalDiscountPrice(totalDiscountPrice);
    }

    public DeliveryNoteAddVO item(String DeliveryNoteId, boolean isPrint) {
        DeliveryNoteAddVO result = new DeliveryNoteAddVO();
        DeliveryNoteDO deliveryNoteDO = deliveryNoteMapper.item(DeliveryNoteId);
        if (deliveryNoteDO == null) {
            return result;
        }
        DeliveryNoteVO deliveryNoteVO = new DeliveryNoteVO();
        BeanUtils.copyProperties(deliveryNoteDO, deliveryNoteVO);
        Integer forward = deliveryNoteDO.getForward();
        forward = forward == null ? ForwardBarcodeLableEnum.NO_FORWARD_BARCODE.getLable() : forward;
        deliveryNoteVO.setForward(forward);
        deliveryNoteVO.setCashShortAndOver(DecimalUtil.fen2yuan(deliveryNoteDO.getCashShortAndOver()));
        if (isPrint && deliveryNoteDO.getIsPrint().equals(0)) {
            DeliveryNoteDO deliveryNoteDO1 = new DeliveryNoteDO();
            deliveryNoteDO1.setIsPrint(1);
            deliveryNoteDO1.setId(deliveryNoteDO.getId());
            deliveryNoteMapper.update(deliveryNoteDO1);
        }
        //获取发货通知单对应的销售订单详情信息
        Map<String, SaleIntentionDetailDO> intentionDetailMap = getIntentionDetailMap(deliveryNoteDO);
        takeDecimals(deliveryNoteVO);
        result.setHeaderInfo(deliveryNoteVO);
        List<DeliveryNoteDetailVO> listVO = new ArrayList<>();
        List<DeliveryNoteDetailDO> listDO = deliveryNoteDetailMapper.listForLocationUser(DeliveryNoteId);
        EnableAndOccupyVO enableAndOccupyVO;
        MaterialLocationRelationVO relationVO = new MaterialLocationRelationVO();
        for (DeliveryNoteDetailDO entity : listDO) {
            String materialsNo = entity.getMaterialsNo();
            DeliveryNoteDetailVO model = new DeliveryNoteDetailVO();
            BeanUtils.copyProperties(entity, model);
            model.setPrice(takeDecimals(model.getPrice()));
            model.setApplyTotalPrice(takeDecimals(model.getApplyTotalPrice()));
            SaleIntentionDetailDO detailDO = intentionDetailMap.get(materialsNo);
            BigDecimal anountAfterAdjust = detailDO == null ? BigDecimal.ZERO :
                    detailDO.getAmountAfterAdjust() == null ? BigDecimal.ZERO : detailDO.getAmountAfterAdjust();
            model.setAmountAfterAdjust(anountAfterAdjust);
            model.setUnitPriceAfterAdjust(takeDecimals(model.getUnitPriceAfterAdjust()));
            model.setTotalPriceAfterAdjust(takeDecimals(model.getTotalPriceAfterAdjust()));
            enableAndOccupyVO = warehouseInventoryService.findEnableAndOccupyNum(model.getMaterialsNo(), deliveryNoteDO.getSupplierOrgId(), deliveryNoteDO.getOutLocation());
            if (enableAndOccupyVO != null) {
                BeanUtils.copyProperties(enableAndOccupyVO, model);
            }

//            MaterialLocationRelationDO relationDO=materialLocationRelationMapper.findByAreaCode(entity.getMaterialsNo(),deliveryNoteDO.getOutLocation(),deliveryNoteDO.getSupplierOrgId());
//            if(null!=relationDO)
//            {
//                model.setStockLocation(relationDO.getLocationCode());
//            }
            relationVO.setOrgId(deliveryNoteDO.getSupplierOrgId());
            relationVO.setMaterialNo(materialsNo);
            relationVO.setWarehouseCode(deliveryNoteDO.getOutLocation());
            relationVO.setAreaCode(deliveryNoteDO.getOutArea());

            MarketingActivityDO marketingActivityDO = marketingActivityMapper.item(model.getPriceSchemeId());
            if (marketingActivityDO == null && !StringUtil.isNullOrEmpty(model.getPriceSchemeName())) {
                marketingActivityDO = marketingActivityMapper.findByName(model.getOrgId(), model.getPriceSchemeName());
            }
            model.setOtherRemark("0");
            if (marketingActivityDO != null) {
                model.setPriceGroup(marketingActivityDO.getPriceGroup());
                MarketingMaterialsVO marketingMaterialsVO = marketingMaterialsMapper.itemByActivityMaterials(model.getOrgId(), materialsNo, entity.getPriceSchemeId());
                if (marketingMaterialsVO != null) {
                    marketingMaterialsVO.setPrice(marketingMaterialsVO.getPrice() == null ? new BigDecimal(0) : marketingMaterialsVO.getPrice());
                    switch (takeDecimals(marketingMaterialsVO.getPrice()).compareTo(model.getUnitPriceAfterAdjust())) {
                        case 1:
                            model.setOtherRemark("1");
                            break;
                        case 0:
                            model.setOtherRemark("2");
                            break;
                        case -1:
                            model.setOtherRemark("3");
                            break;
                    }
                }
            }
            MaterialLocationRelationVO materialLocationRelationVO = new MaterialLocationRelationVO();
            materialLocationRelationVO.setMaterialNo(materialsNo);
            materialLocationRelationVO.setOrgId(deliveryNoteDO.getSupplierOrgId());
            List<MaterialLocationRelationVO> voList = materialLocationRelationMapper.list(materialLocationRelationVO);
            model.setStockLocationList(voList);

            if (StringUtil.isNullOrEmpty(model.getStatus())) {
                model.setStatus("0");//返回默认状态，页面控制按钮时需要
            }
            String locationCodeStr = entity.getLocationCodeStr();
            getLocationDes(model, locationCodeStr);
            listVO.add(model);
        }
        //按照储位排序
        sortReuslt(listVO);
        result.setMaterialList(listVO);
        return result;
    }

    private Map<String, SaleIntentionDetailDO> getIntentionDetailMap(DeliveryNoteDO deliveryNoteDO) {
        Map<String, SaleIntentionDetailDO> result = new HashMap<>();
        if (deliveryNoteDO == null) {
            return result;
        }
        String saleNo = deliveryNoteDO.getSaleNo();
        if (StringUtils.isEmpty(saleNo)) {
            return result;
        }
        List<SaleIntentionDetailDO> intentionDetails = saleIntentionDetailMapper.getBySaleNo(saleNo);
        for (SaleIntentionDetailDO detailDO : intentionDetails) {
            String materialsNo = detailDO.getMaterialsNo();
            if (StringUtils.isEmpty(materialsNo)) {
                continue;
            }
            result.put(materialsNo, detailDO);
        }
        return result;
    }

    /**
     * @Des 打印时获取发货通知单信息
     * @Date 2020/12/29 17:05
     * @Author wangzhaoyu
     * @Param [DeliveryNoteId, isPrint]
     * @Return xcmg.device.service.vo.delivery.DeliveryNoteAddVO
     */
    public DeliveryNoteAddVO itemPrintInfo(String DeliveryNoteId, boolean isPrint) {
        DeliveryNoteAddVO result = new DeliveryNoteAddVO();
        DeliveryNoteDO deliveryNoteDO = deliveryNoteMapper.item(DeliveryNoteId);
        if (deliveryNoteDO == null) {
            return result;
        }
        DeliveryNoteVO deliveryNoteVO = new DeliveryNoteVO();
        BeanUtils.copyProperties(deliveryNoteDO, deliveryNoteVO);
        deliveryNoteVO.setCashShortAndOver(DecimalUtil.fen2yuan(deliveryNoteDO.getCashShortAndOver()));
        if (isPrint && deliveryNoteDO.getIsPrint().equals(0)) {
            DeliveryNoteDO deliveryNoteDO1 = new DeliveryNoteDO();
            deliveryNoteDO1.setIsPrint(1);
            deliveryNoteDO1.setId(deliveryNoteDO.getId());
            deliveryNoteMapper.update(deliveryNoteDO1);
        }
        takeDecimals(deliveryNoteVO);
        result.setHeaderInfo(deliveryNoteVO);
        List<DeliveryNoteDetailVO> listVO = new ArrayList<>();
        List<DeliveryNoteDetailDO> listDO = deliveryNoteDetailMapper.listForLocationUser(DeliveryNoteId);
        for (DeliveryNoteDetailDO entity : listDO) {
            DeliveryNoteDetailVO model = new DeliveryNoteDetailVO();
            BeanUtils.copyProperties(entity, model);
            model.setPrice(takeDecimals(model.getPrice()));
            model.setApplyTotalPrice(takeDecimals(model.getApplyTotalPrice()));
            model.setAmountAfterAdjust(model.getAmountAfterAdjust());
            model.setUnitPriceAfterAdjust(takeDecimals(model.getUnitPriceAfterAdjust()));
            model.setTotalPriceAfterAdjust(takeDecimals(model.getTotalPriceAfterAdjust()));
            String status = entity.getStatus();
            if (!StringUtils.isEmpty(status) && status.equals(3)) {//结单状态，显示出库已出库数量
                BigDecimal deliveryQty = entity.getDeliveryQty() == null ? BigDecimal.ZERO : entity.getDeliveryQty();
                model.setDeliveryQty(deliveryQty);
            }

            MarketingActivityDO marketingActivityDO = marketingActivityMapper.item(model.getPriceSchemeId());
            if (marketingActivityDO == null && !StringUtil.isNullOrEmpty(model.getPriceSchemeName())) {
                marketingActivityDO = marketingActivityMapper.findByName(model.getOrgId(), model.getPriceSchemeName());
            }
            model.setOtherRemark("0");
            if (marketingActivityDO != null) {
                model.setPriceGroup(marketingActivityDO.getPriceGroup());
                MarketingMaterialsVO marketingMaterialsVO = marketingMaterialsMapper.itemByActivityMaterials(model.getOrgId(), entity.getMaterialsNo(), entity.getPriceSchemeId());
                if (marketingMaterialsVO != null) {
                    marketingMaterialsVO.setPrice(marketingMaterialsVO.getPrice() == null ? new BigDecimal(0) : marketingMaterialsVO.getPrice());
                    switch (takeDecimals(marketingMaterialsVO.getPrice()).compareTo(model.getUnitPriceAfterAdjust())) {
                        case 1:
                            model.setOtherRemark("1");
                            break;
                        case 0:
                            model.setOtherRemark("2");
                            break;
                        case -1:
                            model.setOtherRemark("3");
                            break;
                    }
                }
            }
            MaterialLocationRelationVO materialLocationRelationVO = new MaterialLocationRelationVO();
            materialLocationRelationVO.setMaterialNo(entity.getMaterialsNo());
            materialLocationRelationVO.setOrgId(deliveryNoteDO.getSupplierOrgId());
            List<MaterialLocationRelationVO> voList = materialLocationRelationMapper.list(materialLocationRelationVO);
            model.setStockLocationList(voList);
            String locationCodeStr = entity.getLocationCodeStr();
            getLocationDes(model, locationCodeStr);
            listVO.add(model);
        }
        //按照储位排序
        sortReuslt(listVO);
        result.setMaterialList(listVO);
        return result;
    }

    private void sortReuslt(List<DeliveryNoteDetailVO> listVO) {
        Collections.sort(listVO, new Comparator<DeliveryNoteDetailVO>() {
            @Override
            public int compare(DeliveryNoteDetailVO o1, DeliveryNoteDetailVO o2) {
                String locationCodeStr1 = o1.getLocationCodeStr();
                String locationCodeStr2 = o2.getLocationCodeStr();

                if (StringUtils.isEmpty(locationCodeStr1) && StringUtils.isEmpty(locationCodeStr2)) {
                    return 0;
                } else if (StringUtils.isEmpty(locationCodeStr1)) {
                    return -1;
                } else if (StringUtils.isEmpty(locationCodeStr2)) {
                    return 1;
                } else {
                    return locationCodeStr1.compareTo(locationCodeStr2);
                }
            }
        });
    }

    private void getLocationDes(DeliveryNoteDetailVO model, String locationCodeStr) {
        if (StringUtils.isBlank(locationCodeStr)) {
            return;
        }
        String[] locationCodeArr = locationCodeStr.split(",");
        List<String> locationDesArr = new ArrayList<>();
        for (String locationCode : locationCodeArr) {
            locationDesArr.add(warehouseAreaLocationDOMapper.getLocationDesc(locationCode));
        }
        String locationDes = join(locationDesArr, ",");
        model.setLocationDesc(locationDes);

    }

    public void export(List<String> deliveryNoteIds) throws Exception {
        List<DeliveryNoteVO> voList = new ArrayList<>();
        for (String abnormalOutId : deliveryNoteIds) {
            DeliveryNoteDO entity = deliveryNoteMapper.item(abnormalOutId);
            DeliveryNoteVO model = new DeliveryNoteVO();
            BeanUtils.copyProperties(entity, model);
            voList.add(model);
            if (model != null) {
                voList.add(model);
            }
        }
        invokeExport(voList);
    }

    /**
     * 导出发货通知单零件详细列表
     *
     * @param deliveryNoteIds List<String>
     * @throws Exception Exception
     */
    public void exportDetails(List<String> deliveryNoteIds) throws Exception {
        List<DeliveryNoteVO> voList = new ArrayList<>();
        List<ExportDeliveryDetailsVO> deliveryDetailsVOs = new ArrayList<>();

        for (String tempId : deliveryNoteIds) {
            DeliveryNoteDO entity = deliveryNoteMapper.item(tempId);

            List<DeliveryNoteDetailDO> listDO = deliveryNoteDetailMapper.listForLocationUser(tempId);
            if (ListUtil.isNullOrEmpty(listDO)) {
                continue;
            }

            for (DeliveryNoteDetailDO noteDetailDO : listDO) {
                ExportDeliveryDetailsVO deliveryDetailsVO = new ExportDeliveryDetailsVO();
                deliveryDetailsVO.setDeliveryNoteNo(entity.getDeliveryNo());
                deliveryDetailsVO.setSaleNo(entity.getSaleNo());
                deliveryDetailsVO.setPurchaseNo(entity.getPurchaseNo());
                deliveryDetailsVO.setPurchaseOrgId(entity.getPurchaseOrgId());
                deliveryDetailsVO.setPurchaseOrgName(entity.getPurchaseOrgName());
                deliveryDetailsVO.setOutLocation(entity.getOutLocation());
                deliveryDetailsVO.setSapSaleOrder(entity.getSapSaleOrder());
                deliveryDetailsVO.setSapOutBill(entity.getSapOutBill());
                deliveryDetailsVO.setStatus(noteDetailDO.getStatus());
                deliveryDetailsVO.setSettleTypeId(entity.getSettleTypeId());
                deliveryDetailsVO.setSettleTypeName(entity.getSettleTypeName());
                deliveryDetailsVO.setLogState(entity.getLogState());
                deliveryDetailsVO.setLogStateDescribe(entity.getLogStateDescribe());
                deliveryDetailsVO.setCreateDate(entity.getCreateDate());
                deliveryDetailsVO.setTotalPrice(takeDecimals(entity.getTotalDiscountPrice()));
                SaleIntentionDetailDO saleIntentionDetailDO = saleIntentionDetailMapper.selectByNo(entity.getSaleNo(), noteDetailDO.getMaterialsNo());

                deliveryDetailsVO.setMaterialsNo(noteDetailDO.getMaterialsNo());
                deliveryDetailsVO.setMaterialsDesc(noteDetailDO.getMaterialsDes());
                deliveryDetailsVO.setUnit(noteDetailDO.getUnit());
                deliveryDetailsVO.setPrice(takeDecimals(saleIntentionDetailDO.getUnitPriceAfterAdjust()));//获取销售意向明细中零件调整后价格
                deliveryDetailsVO.setTotalDetailPrice(takeDecimals(noteDetailDO.getTotalPriceAfterAdjust()));
                deliveryDetailsVO.setAmountAfterAdjust(noteDetailDO.getAmountAfterAdjust());
                deliveryDetailsVO.setInventoryOutAmount(noteDetailDO.getInventoryOutAmount());
                deliveryDetailsVO.setDeliveryQty(noteDetailDO.getDeliveryQty());
                deliveryDetailsVO.setUpdateStateDate(entity.getUpdateStateDate());

                deliveryDetailsVO.setCountry(entity.getCountry());
                deliveryDetailsVO.setStockLocation(noteDetailDO.getStockLocation());
                deliveryDetailsVO.setStockUserName(noteDetailDO.getStockUserName());
                deliveryDetailsVO.setInvoiceFlag(noteDetailDO.getInvoiceFlag());
                deliveryDetailsVOs.add(deliveryDetailsVO);
            }
        }
        invokeExportDetails(deliveryDetailsVOs);
    }


    public void exportAll(DeliveryNoteVO condition) throws Exception {
        //PageHelperPlus.startPage(0, 0, "application_date desc");
        List<DeliveryNoteVO> voList = new ArrayList<>();
        condition.setBillNosList(xcmg.device.infra.StringUtil.splitList(condition.getBillNos()));
        condition.setPurchaseNamesList(xcmg.device.infra.StringUtil.splitList(condition.getPurchaseNames()));
        List<DeliveryNoteDO> doList = deliveryNoteMapper.list(condition);
        for (DeliveryNoteDO entity : doList) {
            DeliveryNoteVO model = new DeliveryNoteVO();
            BeanUtils.copyProperties(entity, model);
            voList.add(model);
        }
        invokeExport(voList);
    }


    public void exportDetailsAll(DeliveryNoteVO condition) throws Exception {
        String title = "发货通知数据导出";
        String[] rowsName = new String[]{"序号", "发货通知单号", "销售意向", "采购单号", "单据价格", "国家", "客户代码", "客户名称", "发出库位", "Sap销售订单", "Sap外向发货单", "零件编码", "零件名称", "单位", "销售单价", "销售总价", "需求发货数", "实际出库数", "本次发货数量", "出库状态", "出库时间", "结算方式", "物流状态", "制单时间", "储位", "保管员", "是否开票"};
        List<Object[]> dataList = new ArrayList<>();
        int i = 1;

        condition.setBillNosList(xcmg.device.infra.StringUtil.splitList(condition.getBillNos()));
        condition.setPurchaseNamesList(xcmg.device.infra.StringUtil.splitList(condition.getPurchaseNames()));
        PageHelperPlus.startPage(0, 60000);
        List<DeliveryNoteExportDO> deliveryNoteExportDOList = deliveryNoteMapper.exportAllList(condition);
        for (DeliveryNoteExportDO entity : deliveryNoteExportDOList) {
            ExportDeliveryDetailsVO deliveryDetailsVO = getExportDeliveryDetailsVO(entity);
            i = getExportDetailsDate(rowsName, dataList, i, deliveryDetailsVO);
        }
        ExportUtil exportUtil = new ExportUtil(title, rowsName, dataList);
        exportUtil.export(response);
    }

    private ExportDeliveryDetailsVO getExportDeliveryDetailsVO(DeliveryNoteExportDO entity) {
        ExportDeliveryDetailsVO deliveryDetailsVO = new ExportDeliveryDetailsVO();
        deliveryDetailsVO.setDeliveryNoteNo(entity.getDeliveryNo());
        deliveryDetailsVO.setSaleNo(entity.getSaleNo());
        deliveryDetailsVO.setPurchaseNo(entity.getPurchaseNo());
        deliveryDetailsVO.setPurchaseOrgId(entity.getPurchaseOrgId());
        deliveryDetailsVO.setPurchaseOrgName(entity.getPurchaseOrgName());
        deliveryDetailsVO.setOutLocation(entity.getOutLocation());
        deliveryDetailsVO.setSapSaleOrder(entity.getSapSaleOrder());
        deliveryDetailsVO.setSapOutBill(entity.getSapOutBill());
        deliveryDetailsVO.setStatus(entity.getStatus());
        deliveryDetailsVO.setSettleTypeId(entity.getSettleTypeId());
        deliveryDetailsVO.setSettleTypeName(entity.getSettleTypeName());
        deliveryDetailsVO.setLogState(entity.getLogState());
        deliveryDetailsVO.setLogStateDescribe(entity.getLogStateDescribe());
        deliveryDetailsVO.setCreateDate(entity.getCreateDate());
        deliveryDetailsVO.setTotalPrice(takeDecimals(entity.getTotalDiscountPrice()));

        deliveryDetailsVO.setMaterialsNo(entity.getMaterialsNo());
        deliveryDetailsVO.setMaterialsDesc(entity.getMaterialsDes());
        deliveryDetailsVO.setUnit(entity.getUnit());
        BigDecimal price = BigDecimal.ZERO;
        if (entity.getUnitPriceAfterAdjust() != null) {
            price = takeDecimals(entity.getUnitPriceAfterAdjust());
        }
        deliveryDetailsVO.setPrice(price);//获取销售意向明细中零件调整后价格
        deliveryDetailsVO.setTotalDetailPrice(takeDecimals(entity.getTotalPriceAfterAdjust()));
        deliveryDetailsVO.setAmountAfterAdjust(entity.getAmountAfterAdjust());
        deliveryDetailsVO.setInventoryOutAmount(entity.getInventoryOutAmount());
        deliveryDetailsVO.setDeliveryQty(entity.getDeliveryQty());
        deliveryDetailsVO.setUpdateStateDate(entity.getUpdateStateDate());
        deliveryDetailsVO.setCountry(entity.getCountry());
        deliveryDetailsVO.setStockLocation(entity.getStockLocation());
        deliveryDetailsVO.setStockUserName(entity.getStockUserName());
        deliveryDetailsVO.setInvoiceFlag(entity.getInvoiceFlag());
        return deliveryDetailsVO;
    }

    private int getExportDetailsDate(String[] rowsName, List<Object[]> dataList, int i, ExportDeliveryDetailsVO deliveryDetailsVO) {
        Object[] objs = new Object[rowsName.length];
        objs[0] = i;
        objs[1] = deliveryDetailsVO.getDeliveryNoteNo();
        objs[2] = deliveryDetailsVO.getSaleNo();
        objs[3] = deliveryDetailsVO.getPurchaseNo();
        objs[4] = deliveryDetailsVO.getTotalPrice();
        objs[5] = deliveryDetailsVO.getCountry();
        objs[6] = deliveryDetailsVO.getPurchaseOrgId();
        objs[7] = deliveryDetailsVO.getPurchaseOrgName();
        objs[8] = deliveryDetailsVO.getOutLocation();
        objs[9] = deliveryDetailsVO.getSapSaleOrder();
        objs[10] = deliveryDetailsVO.getSapOutBill();
        objs[11] = deliveryDetailsVO.getMaterialsNo();
        objs[12] = deliveryDetailsVO.getMaterialsDesc();
        objs[13] = deliveryDetailsVO.getUnit();
        objs[14] = deliveryDetailsVO.getPrice();
        objs[15] = deliveryDetailsVO.getTotalDetailPrice();
        objs[16] = deliveryDetailsVO.getAmountAfterAdjust();
        objs[17] = deliveryDetailsVO.getInventoryOutAmount();
        objs[18] = deliveryDetailsVO.getDeliveryQty();
        String isOut = deliveryDetailsVO.getStatus();
        if ("1".equals(isOut)) {
            objs[19] = "部分出库";
        } else if ("2".equals(isOut)) {
            objs[19] = "已出库";
        } else if ("3".equals(isOut)) {
            objs[19] = "强制结单";
        } else {
            objs[19] = "未出库";
        }

        objs[20] = DateUtil.formatDateTime(deliveryDetailsVO.getUpdateStateDate());
        objs[21] = deliveryDetailsVO.getSettleTypeName();
        objs[22] = deliveryDetailsVO.getLogState();
        objs[23] = DateUtil.formatDateTime(deliveryDetailsVO.getCreateDate());
        objs[24] = deliveryDetailsVO.getStockLocation();
        objs[25] = deliveryDetailsVO.getStockUserName();
        if (deliveryDetailsVO.getInvoiceFlag() != null && deliveryDetailsVO.getInvoiceFlag().equals(0)) {
            objs[26] = "否";
        } else if (deliveryDetailsVO.getInvoiceFlag() != null && deliveryDetailsVO.getInvoiceFlag().equals(1)) {
            objs[26] = "是";
        } else {
            objs[26] = "否";
        }
        dataList.add(objs);
        i++;
        return i;
    }

    private void invokeExport(List<DeliveryNoteVO> voList) throws Exception {
        String title = "发货通知数据导出";
        String[] rowsName = new String[]{"序号", "发货通知单号", "销售意向单号", "客户采购订单编号", "国家", "客户代码", "发出仓库", "Sap销售订单", "Sap外向发货单", "出库状态", "出库时间", "结算方式", "物流状态", "申请人", "申请日期"};
        List<Object[]> dataList = new ArrayList<Object[]>();
        Object[] objs = null;
        for (int i = 0; i < voList.size(); i++) {
            DeliveryNoteVO e = voList.get(i);
            objs = new Object[rowsName.length];
            objs[0] = i + 1;
            objs[1] = e.getDeliveryNo();
            objs[2] = e.getSaleNo();
            objs[3] = e.getCustomerPurchaseCode();
            objs[4] = e.getCountry();
            objs[5] = e.getPurchaseOrgId();
            objs[6] = e.getOutLocation();
            objs[7] = e.getSapSaleOrder();
            objs[8] = e.getSapOutBill();
            objs[9] = getStatusDesc(e.getIsOut());
            objs[10] = e.getUpdateStateDate() == null ? "" : DateUtil.formatDateTime(e.getUpdateStateDate());
            objs[11] = e.getSettleTypeName();
            objs[12] = getStatusDesc(e.getLogStateDescribe());
            objs[13] = e.getCreatorId();
            objs[14] = e.getApplicationDate();
            dataList.add(objs);
        }
        ExportUtil exportUtil = new ExportUtil(title, rowsName, dataList);
        exportUtil.export(response);
    }

    private void invokeExportDetails(List<ExportDeliveryDetailsVO> voList) throws Exception {
        String title = "发货通知数据导出";
        String[] rowsName = new String[]{"序号", "发货通知单号", "销售意向", "采购单号", "单据价格", "国家", "客户代码",
                "客户名称", "发出库位", "Sap销售订单", "Sap外向发货单", "零件编码", "零件名称", "单位", "销售单价", "销售总价",
                "需求发货数", "实际出库数", "本次发货数量", "出库状态", "出库时间", "结算方式", "物流状态", "制单时间", "储位",
                "保管员", "是否开票"};
        List<Object[]> dataList = new ArrayList<Object[]>();
        Object[] objs = null;
        for (int i = 0; i < voList.size(); i++) {
            ExportDeliveryDetailsVO e = voList.get(i);
            objs = new Object[rowsName.length];
            objs[0] = i + 1;
            objs[1] = e.getDeliveryNoteNo();
            objs[2] = e.getSaleNo();
            objs[3] = e.getPurchaseNo();
            objs[4] = e.getTotalPrice();
            objs[5] = e.getCountry();
            objs[6] = e.getPurchaseOrgId();
            objs[7] = e.getPurchaseOrgName();
            objs[8] = e.getOutLocation();
            objs[9] = e.getSapSaleOrder();
            objs[10] = e.getSapOutBill();
            objs[11] = e.getMaterialsNo();
            objs[12] = e.getMaterialsDesc();
            objs[13] = e.getUnit();
            objs[14] = e.getPrice();
            objs[15] = e.getTotalDetailPrice();
            objs[16] = e.getAmountAfterAdjust();
            objs[17] = e.getInventoryOutAmount();
            objs[18] = e.getDeliveryQty();
            String isOut = e.getStatus();
            if ("1".equals(isOut)) {
                objs[19] = "部分出库";
            } else if ("2".equals(isOut)) {
                objs[19] = "已出库";
            } else if ("3".equals(isOut)) {
                objs[19] = "强制结单";
            } else {
                objs[19] = "未出库";
            }

            objs[20] = DateUtil.formatDateTime(e.getUpdateStateDate());
            objs[21] = e.getSettleTypeName();
            objs[22] = e.getLogState();
            objs[23] = DateUtil.formatDateTime(e.getCreateDate());
            objs[24] = e.getStockLocation();
            objs[25] = e.getStockUserName();
            if (e.getInvoiceFlag() != null && e.getInvoiceFlag().equals(0)) {
                objs[26] = "否";
            } else if (e.getInvoiceFlag() != null && e.getInvoiceFlag().equals(1)) {
                objs[26] = "是";
            } else {
                objs[26] = "否";
            }

            dataList.add(objs);
        }
        ExportUtil exportUtil = new ExportUtil(title, rowsName, dataList);
        exportUtil.export(response);
    }

    private String getStatusDesc(String statusId) {
        switch (statusId) {
            case "0":
            default:
                return "未开始";
            case "1":
                return "正在进行";
            case "2":
                return "已完成";
        }

    }

    //更新发货通知出入库状态和物流状态
    public boolean updateStatus(String deliveryNo, String materialsNo, String logStatus, String isOut) {
        DeliveryNoteDetailVO noteVO = new DeliveryNoteDetailVO();
        noteVO.setDeliveryNoteNo(deliveryNo);
        noteVO.setMaterialsNo(materialsNo);
        List<DeliveryNoteDetailDO> list = deliveryNoteDetailMapper.listAll(noteVO);
        if (ListUtil.isNullOrEmpty(list)) {
            return false;
        }
        DeliveryNoteDetailDO noteDO = list.get(0);
        boolean success = deliveryNoteDetailMapper.update(noteDO) > 0;
        if (success) {
            DeliveryNoteVO outVO = new DeliveryNoteVO();
            outVO.setDeliveryNo(deliveryNo);
            List<DeliveryNoteDO> outList = deliveryNoteService.list(outVO);
            if (ListUtil.isNullOrEmpty(outList)) {
                return false;
            }
            DeliveryNoteDO outDO = outList.get(0);
            outDO.setLogState("2");
            outDO.setIsOut("0");
            outDO.setIsOutDesc(DeliveryNoteOutStatusEnum.getDescByStatus("0"));
            success = deliveryNoteService.updateBy(outDO);
        }
        return success;
    }

    //
    //    //更新已发数量接口
    //    public ErrorCode updateInventoryOut(BigDecimal inventoryOutAmount,String deliveryNo,
    //                                        String materialsNo,BigDecimal deliveryQty){
    //        if(inventoryOutAmount==null){
    //            return ErrorCode.IllegalArument;
    //        }
    //        String isOut="0";
    //        DeliveryNoteDetailDO deliveryNoteDetailDO = new DeliveryNoteDetailDO();
    //        deliveryNoteDetailDO.setInventoryOutAmount(inventoryOutAmount);
    //        deliveryNoteDetailDO.setMaterialsNo(materialsNo);
    //        deliveryNoteDetailDO.setDeliveryNoteNo(deliveryNo);
    //        //已发运数==本次发货数量？？
    //        if(!inventoryOutAmount.equals(deliveryQty)){
    //            isOut="1";
    //        }
    //        if(deliveryNoteMapper.updateStatus(isOut,deliveryNo)==0){
    //            return ErrorCode.Failure;
    //        }
    //        deliveryNoteDetailMapper.updateInventoryOut(deliveryNoteDetailDO);
    //        return ErrorCode.Success;
    //    }

    //根据入库表更新发货通知状态

    @Transactional(rollbackFor = Exception.class)
    public boolean updateByDelivery(String deliveryNo, String materialsNo, BigDecimal inventoryOutAmount, String status, String isOut, String orgId, boolean updateReceipt) throws Exception {
        DeliveryNoteDetailVO noteVO = new DeliveryNoteDetailVO();
        DeliveryNoteDO deliveryNoteDO = deliveryNoteMapper.itemByNo(deliveryNo, orgId);
        if (deliveryNoteDO == null) {
            return false;
        }
        noteVO.setDeliveryNoteNo(deliveryNoteDO.getId());
        noteVO.setMaterialsNo(materialsNo);
        noteVO.setOrgId(orgId);
        List<DeliveryNoteDetailDO> list = deliveryNoteDetailMapper.listAll(noteVO);
        if (ListUtil.isNullOrEmpty(list)) {
            return false;
        }
        DeliveryNoteDetailDO noteDO = list.get(0);
        BigDecimal nowAmount = inventoryOutAmount.subtract(noteDO.getInventoryOutAmount());
        noteDO.setInventoryOutAmount(inventoryOutAmount);
        noteDO.setStatus(status);
        boolean success = deliveryNoteDetailMapper.update(noteDO) > 0;
        if (success) {
            DeliveryNoteDO newDeliveryNoteDO = new DeliveryNoteDO();
            newDeliveryNoteDO.setId(deliveryNoteDO.getId());
            newDeliveryNoteDO.setIsOut(isOut);
            newDeliveryNoteDO.setUpdateStateDate(new Date());

            newDeliveryNoteDO.setIsOutDesc(DeliveryNoteOutStatusEnum.getDescByStatus(isOut));

            success = deliveryNoteService.updateBy(newDeliveryNoteDO);
            if (!success) {
                return false;
            }

            //saleIntentionMapper.updateOutStatus(deliveryNoteDO.getSaleNo(),Integer.valueOf(isOut));

            //更新销售意向单已出库数量
            success = saleIntentionService.updateByOutBound(deliveryNoteDO.getSaleNo(), materialsNo, nowAmount, orgId);

            if (!success) {
                return false;
            }

            if (updateReceipt) {
                //更新发运交接单状态
                List<String> ids = deliveryReceiptLinkMapper.findReceiptIds(deliveryNoteDO.getId());
                if (!ListUtil.isNullOrEmpty(ids)) {
                    List<DeliveryReceiptMaterialDO> receiptMaterialDOList = deliveryReceiptMaterialMapper.listByIds(ids, materialsNo);
                    if (!ListUtil.isNullOrEmpty(receiptMaterialDOList)) {
                        for (DeliveryReceiptMaterialDO receiptMaterialDO : receiptMaterialDOList) {
                            deliveryReceiptMaterialService.updateByOut(receiptMaterialDO, receiptMaterialDO.getOutQty().add(nowAmount));
                        }
                    }
                }
            }
        }
        return success;
    }


    public boolean updateBy(DeliveryNoteDO deliveryNoteDO) {
        return deliveryNoteMapper.update(deliveryNoteDO) > 0;
    }

    public List<DeliveryNoteDO> list(DeliveryNoteVO vo) {
        return deliveryNoteMapper.list(vo);
    }

    /**
     * 修改发货通知单退货状态
     *
     * @param deliveryId String 发货单主键ID
     * @param status     Integer 退货状态（0未退货，1退货中，2退货完成）
     * @return ErrorCode
     */
    public ErrorCode updateReturnStatus(String deliveryId, Integer status) {
        deliveryNoteMapper.updateReturnStatus(deliveryId, status);

        deliveryNoteDetailMapper.updateReturnStatusByNo(deliveryId, status);

        return ErrorCode.Success;
    }

    /**
     * 根据销售单号更新更新发货单状态
     *
     * @param saleNo String
     * @param status Integer
     * @return ErrorCode
     */
    public ErrorCode updateReturnStatusBySaleNo(String saleNo, Integer status) {
        deliveryNoteMapper.updateReturnStatusBySaleNo(saleNo, status);
        return ErrorCode.Success;
    }


    /**
     * @Author: WangKe
     * @Description: 更新发货通知单和出库事务单的冲销状态
     * @Date: 2018/3/22 0022
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean updateReverseState(DeliveryNoteDO deliveryNoteDO, Integer state, String orgId) throws Exception {
        DeliveryNoteDO noteDO = new DeliveryNoteDO();
        noteDO.setId(deliveryNoteDO.getId());
        noteDO.setIsReverse(state);
        boolean success = deliveryNoteMapper.update(noteDO) > 0;
        if (!success) {
            throw new Exception("更新发货通知单状态失败");
        }
        WarehouseDeliveryDO deliveryDO = warehouseDeliveryMapper.findByBusinessOrder(deliveryNoteDO.getDeliveryNo(), orgId);
        if (deliveryDO == null) {
            throw new Exception("未找到相关联的出库事务单");
        }
        deliveryDO.setReverseState(state);
        success = warehouseDeliveryMapper.updateByPrimaryKey(deliveryDO) > 0;
        if (!success) {
            throw new Exception("更新出库事务单状态失败");
        }
        return true;
    }

//    /**
//     * 发货通知单(提前)过账
//     *
//     * @param id
//     * @param orgId
//     * @return
//     * @throws Exception
//     */
//    @Transactional(rollbackFor = Exception.class)
//    public ErrorCode postSap(String id, String orgId, String userId, String userName) throws Exception {
//        DeliveryNoteDO deliveryNoteDO = deliveryNoteMapper.item(id);
//
//        if (CompanyUtil.isWJ(orgId)) {
//            postFilterForWJ(deliveryNoteDO);
//        }
//
//        if (deliveryNoteDO == null) {
//            return ErrorCode.ImportExcelNoData;
//        }
//        if (deliveryNoteDO.hasPosted()) {
//            return ErrorCode.PostError;
//        }
//        // 判断是否允许过账
//        if (!canPost(deliveryNoteDO)) {
//            return ErrorCode.DeliveryReceiptNotShiped;
//        }
//        CompanyInfoVO companyInfoVO = companyInfoService.info(orgId);
//        if (companyInfoVO == null || companyInfoVO.getSapCode() == null) {
//            LogHelper.error("同步sap过账时企业不存在", ErrorCode.RequestIdError.getCode());
//            return ErrorCode.ImportExcelNoData;
//        }
//        ImportParam importParam = fillImportParam(deliveryNoteDO, companyInfoVO, userId, userName);
//        LogHelper.monitor("========调用发货通知单过账接口开始========");
//        //发起sap调用前把发货通知单的sap_launch字段设置为1表示已经发起sap请求 add by wangzhaoyu,异常捕捉，不能影响主流程
//        try{
//            deliveryNoteMapper.updateSapLaunch(deliveryNoteDO.getId(),1);
//        }catch (Exception e){ LogHelper.error("初始化发货通知到的SapLaunch为1出现异常",ErrorCode.RequestIdError.getCode());}
//        OutputParam outputParam = null;
//        try{
//            //捕捉异常观察是否是调用sap接口出现异常
//            outputParam = SAPCommonUtil.getData(importParam);
//        }catch (Exception e){
//            LogHelper.monitor("========调用发货通知单过账sap接口异常========"+ JsonUtil.objectToString(e));
//            return ErrorCode.Failure;
//        }
//        //调用成功后更新sap_launch字段设置为0, add by wangzhaoyu
//        try{
//            deliveryNoteMapper.updateSapLaunch(deliveryNoteDO.getId(),2);
//        }catch (Exception e){ LogHelper.error("初始化发货通知到的SapLaunch为0出现异常",ErrorCode.RequestIdError.getCode());}
//        //重新
//        LogHelper.monitor("========调用发货通知单过账接口结束========");
//        if (null == outputParam || outputParam.getCode() != 0) {
//            LogHelper.error("sap返回值为null", ErrorCode.RequestIdError.getCode());
//            throw new Exception("SAP无返回值");
//        }
//        DeliveryNoteDO sapDeliveryNoteDO = null;
//        try{
//            sapDeliveryNoteDO = assemblyDeliveryNote(companyInfoVO,deliveryNoteDO, outputParam);
//        }catch (Exception e){
//            LogHelper.monitor(deliveryNoteDO.getDeliveryNo()+"执行assemblyDeliveryNote出现异常?"+JsonUtil.objectToString(e));
//            throw e;
//        }
//
//
//        // 数据无变化的情况下重复点击“过账”，以下字段均为null
////        if (null == sapDeliveryNoteDO.getSapSaleOrder() && null == sapDeliveryNoteDO.getSapOutBill()
////                && null == sapDeliveryNoteDO.getMaterialsNo() && null == sapDeliveryNoteDO.getIsPosting()) {
////            throw new Exception("操作无效，请勿重复操作");
////        }
//        if (null == sapDeliveryNoteDO.getSapSaleOrder() && null == sapDeliveryNoteDO.getSapOutBill()
//                && null == sapDeliveryNoteDO.getMaterialsNo() && null == sapDeliveryNoteDO.getIsPosting()) {
//            LogHelper.monitor(deliveryNoteDO.getDeliveryNo()+"sapSaleOrder,sapOutBill,materialsNo,isPosting均为空");
//            return ErrorCode.Success;
//        }
//        //捕捉异常，观察是否回滚
//        try{
//            if (deliveryNoteMapper.updateSap(sapDeliveryNoteDO) == 0) {
//                LogHelper.monitor(deliveryNoteDO.getDeliveryNo()+"执行updateSap操作返回结果==0");
//                return ErrorCode.SapUpdateFail;
//            }
//        }catch (Exception e){
//            LogHelper.monitor(deliveryNoteDO.getDeliveryNo()+"执行updateSap出现异常"+e);
//            throw e;
//        }
//        //状态为已过帐，并且主机厂是塔机时更新发货通知单的状态为已出库（同时修改对应销售订单主表和明细的出库状态）http://10.90.1.198/zentao/story-view-2395.html
//        Integer isPosting = sapDeliveryNoteDO.getIsPosting();
//        String sapCode = companyInfoVO.getSapCode();
//        if(isPosting != null && isPosting.compareTo(1) == 0 && sapCode != null && sapCode.equals(CompanyUtil.TJ_SAP_CODE)){
//            sapPostSuccessUpdateOutStatus(deliveryNoteDO);
//        }
//        return ErrorCode.Success;
//    }

    /**
     * @Des 过账成功后更新发货通知单、销售订单主表和明细的出库状态为已出库
     * @Date 2020/12/2 9:56
     * @Author wangzhaoyu
     * @Param []
     * @Return void
     */
    private void sapPostSuccessUpdateOutStatus(DeliveryNoteDO deliveryNoteDO) {
        try {
            //更新发货通知单
            String id = deliveryNoteDO.getId();
            String outStatus = "2";
            String outStatusDesc = DeliveryNoteOutStatusEnum.getDescByStatus(outStatus);
            deliveryNoteMapper.updateIsOut(id, outStatus, outStatusDesc);
            //更新销售订单主表
            String saleNo = deliveryNoteDO.getSaleNo();
            saleIntentionMapper.updateInventoryOutStatus(saleNo, outStatus);
            //更新销售订单子表
            saleIntentionDetailMapper.updateInventoryOutStatus(saleNo, outStatus);
        } catch (Exception e) {
            LogHelper.monitor("过账成功更新发货通知单，销售订单主表及明细状态为出库异常" + e);
        }
    }

    private void postFilterForWJ(DeliveryNoteDO deliveryNoteDO) throws Exception {
        if (StringUtils.equals(deliveryNoteDO.getPurchaseOrgName(), CompanyUtil.IMPORT_EXPORT_COM_NAME) ||
                StringUtils.equals(deliveryNoteDO.getPurchaseOrgName(), CompanyUtil.ZL_COM_NAME)) {
            List<String> idsList = deliveryReceiptLinkMapper.findReceiptIds(deliveryNoteDO.getId());
            if (CollectionUtils.isEmpty(idsList)) {
                throw new Exception("该发货通知单未创建发运交接单");
            }
            List<DeliveryReceiptDO> list = deliveryReceiptMapper.itemByIds(idsList);
            if (CollectionUtils.isEmpty(list)) {
                throw new Exception("该发货通知单未创建发运交接单");
            }
            for (DeliveryReceiptDO receiptDO : list) {
                if (StringUtils.equals(receiptDO.getDeliveryStatus(), "0")) {
                    throw new Exception("发运交接单未出库");
                }
            }
        }
    }

//    /**
//     * 请求sap执行的顺序一定是：创建销售订单->创建外向交货单->外向交货单发货
//     *
//     * @param deliveryNoteDO
//     * @param outputParam
//     * @return
//     * @throws Exception
//     */
//    private DeliveryNoteDO assemblyDeliveryNote(CompanyInfoVO companyInfoVO,DeliveryNoteDO deliveryNoteDO, OutputParam outputParam) throws Exception {
//        DeliveryNoteDO sapDeliveryNoteDO = new DeliveryNoteDO();
//        sapDeliveryNoteDO.setId(deliveryNoteDO.getId());
//        //外向交货单号
//        String sapOutBill = deliveryNoteDO.getSapOutBill();
//        //创建销售订单结果
//        if (null == deliveryNoteDO.getSapSaleOrder()) {
//            if (!RESULT_OK.equals(outputParam.getDataHeader().get("RETURNCODE1"))) {
//                LogHelper.error("调用发货通知单过账接口失败，" + outputParam.getDataHeader().get("RETURNMSG1"), ErrorCode.RequestIdError.getCode());
//                addRecord(sapOutBill,deliveryNoteDO, outputParam.getDataHeader().get("RETURNMSG1"), companyInfoVO);
//                throw new Exception(outputParam.getDataHeader().get("RETURNMSG1"));
//            } else {
//                sapDeliveryNoteDO.setSapSaleOrder(outputParam.getDataHeader().get("VBELN"));
//            }
//        }
//        //创建外向交货单结果
//        if (null == sapOutBill) {
//            if (!RESULT_OK.equals(outputParam.getDataHeader().get("RETURNCODE2"))) {
//                LogHelper.monitor("调用发货通知单过账接口失败，原因可能是操作提前过账，" + outputParam.getDataHeader().get("RETURNMSG2"));
//                addRecord(sapOutBill,deliveryNoteDO, outputParam.getDataHeader().get("RETURNMSG2"), companyInfoVO);
//            } else {
//                sapOutBill = outputParam.getDataHeader().get("DELIV_NUMB");
//                sapDeliveryNoteDO.setSapOutBill(sapOutBill);
//            }
//        }
//        //外向交货单发货结果
//        if (!RESULT_OK.equals(outputParam.getDataHeader().get("RETURNCODE3"))) {
//            LogHelper.monitor("调用发货通知单过账接口失败，原因可能是操作提前过账，" + outputParam.getDataHeader().get("RETURNMSG3"));
//            addRecord(sapOutBill,deliveryNoteDO, outputParam.getDataHeader().get("RETURNMSG3"), companyInfoVO);
//        } else {
//            sapDeliveryNoteDO.setMaterialsNo(outputParam.getDataHeader().get("MBLNR"));
//            sapDeliveryNoteDO.setIsPosting(DeliveryNoteDO.POSTING_YES);
//
//            //过账成功，删除过账失败记录
//            sappostErrorRecordService.updateDel(deliveryNoteDO.getDeliveryNo(), deliveryNoteDO.getSupplierOrgId());
//        }
//        return sapDeliveryNoteDO;
//    }

    //sapOutBill = 外向交货单号
//    private void addRecord(String sapOutBill, DeliveryNoteDO deliveryNoteDO, String errorMessage, CompanyInfoVO companyInfoVO) {
//        SappostErrorRecordDO sappostErrorRecordDO = new SappostErrorRecordDO();
//        String orgId = companyInfoVO.getOrgId();
//        String sapCode = companyInfoVO.getSapCode();
//        sappostErrorRecordDO.setErrorMessage(errorMessage);
//        sappostErrorRecordDO.setBusinessNo(deliveryNoteDO.getDeliveryNo());
//        sappostErrorRecordDO.setOrgId(orgId);
//
//        sappostErrorRecordDO.setOrderCreateId(deliveryNoteDO.getCreatorId());
//        sappostErrorRecordDO.setOrderCreateName(deliveryNoteDO.getCreateName());
//        if (CompanyUtil.isJC(sapCode)) {
//            sappostErrorRecordDO.setSapOrderNo(sapOutBill);//2100（基础），过账失败记录的sap订单号赋值为外向交货单号
//        } else {
//            sappostErrorRecordDO.setSapOrderNo(deliveryNoteDO.getSapSaleOrder());
//        }
//        sappostErrorRecordService.add(sappostErrorRecordDO);
//    }

//    /**
//     * 填充过账相关参数
//     *
//     * @param deliveryNoteDO
//     * @param companyInfoVO
//     * @return
//     */
//    private ImportParam fillImportParam(DeliveryNoteDO deliveryNoteDO, CompanyInfoVO companyInfoVO, String userId, String userName) {
//        List<DeliveryNoteDetailDO> detailDOList = deliveryNoteDetailMapper.list(deliveryNoteDO.getId());
//        ImportParam importParam = new ImportParam();
//        importParam.setFunction("ZPMSBJ_SET_VA01N");
//        Map<String, String> map = new HashMap<>();
//        map.put(SAP_CODE, companyInfoVO.getSapCode());
//        map.put(SOLD, deliveryNoteDO.getSold());
//        map.put(DELIVERY, deliveryNoteDO.getDelivery());
//        map.put(SAP_OUT_AREA, deliveryNoteDO.getSapOutArea());
//        map.put(NOTE, deliveryNoteDO.getNote());
//        map.put(CREATER, deliveryNoteMapper.findUserSapCode(deliveryNoteDO.getCreatorId()));
//        // 提前过账，可能sap系统已经返回过“VBELN”，“DELIV_NUMB”的值
//        if (StringUtil.isNullOrEmpty(deliveryNoteDO.getSapOutBill())) {
//            map.put("DELIV_IN_PR", deliveryNoteDO.getSapOutNo());
//        } else {
//            map.put(SAP_OUT_BILL, deliveryNoteDO.getSapOutBill());
//        }
//        if (!StringUtil.isNullOrEmpty(deliveryNoteDO.getSapSaleOrder())) {
//            map.put(SAP_SALE_ORDER_NO, deliveryNoteDO.getSapSaleOrder());
//        }
//
//        importParam.setCommonParamMap(map);
//        Map<String, List<Map<String, String>>> tableParamMap = new HashMap<>();
//        List<Map<String, String>> list;
//        // 如果是塔机的单子，并且尾差金额不为0则需要特殊处理，否则走正常逻辑
//        BigDecimal cashShortAndOver = deliveryNoteDO.getCashShortAndOver();
//        boolean needSplitPost = CompanyUtil.isTJSapCode(companyInfoVO.getSapCode())
//                && cashShortAndOver != null
//                && cashShortAndOver.compareTo(BigDecimal.ZERO) > 0;
//        if(needSplitPost){
//            list = tjSapPostParam(cashShortAndOver, deliveryNoteDO,detailDOList,companyInfoVO, userId, userName);
//        }else{
//            list = sapPostParam( deliveryNoteDO,detailDOList, companyInfoVO,userId, userName);
//        }
//        tableParamMap.put("ZWJBJ_VA01_IN", list);
//        importParam.setTableParamMap(tableParamMap);
//        importParam.setSapCode(companyInfoVO.getSapCode());
//        return importParam;
//    }

//    /**
//     * @Des 发货通知单过账无聊详情参数拼接
//     * @Date 2020/11/11 17:09
//     * @Author wangzhaoyu
//     * @Param [deliveryNoteDO, detailDOList, companyInfoVO, userId, userName]
//     * @Return java.util.List<java.util.Map<java.lang.String,java.lang.String>>
//     */
//    private List<Map<String, String>> sapPostParam(DeliveryNoteDO deliveryNoteDO,List<DeliveryNoteDetailDO> detailDOList,CompanyInfoVO companyInfoVO,String userId,String userName){
//
//        List<Map<String, String>> list = new ArrayList<>();
//        for (DeliveryNoteDetailDO detailDO : detailDOList) {
//            Map<String, String> mapd = new HashMap<>();
//            mapd.put(MATERIALS_NO, detailDO.getMaterialsNo());
//            if ("0".equals(deliveryNoteDO.getIsOut())) {
//                mapd.put(MATERIALS_QTY, detailDO.getDeliveryQty().toString());
//            } else {
//                if (detailDO.getInventoryOutAmount().equals(BigDecimal.ZERO)) {
//                    continue;
//                }
//                mapd.put(MATERIALS_QTY, detailDO.getInventoryOutAmount().toString());
//            }
//            mapd.put(UNIT, detailDO.getUnit());
//            mapd.put(PRICE, takeDecimals(detailDO.getUnitPriceAfterAdjust()).toString());
//            MarketingActivityDO marketingActivityDO = marketingActivityMapper.item(detailDO.getPriceSchemeId());
//            if (marketingActivityDO == null && !StringUtil.isNullOrEmpty(detailDO.getPriceSchemeName())) {
//                marketingActivityDO = marketingActivityMapper.findByName(companyInfoVO.getOrgId(), detailDO.getPriceSchemeName());
//                if (marketingActivityDO != null) {
//                    mapd.put(PRICE_GROUP, marketingActivityDO.getPriceGroup());
//                }
//            } else {
//                mapd.put(PRICE_GROUP, "");
//            }
//            list.add(mapd);
//
//            //插入过账记录
//            insertPostRecord(deliveryNoteDO.getId(), deliveryNoteDO.getDeliveryNo(), detailDO.getMaterialsNo(), detailDO.getInventoryOutAmount(),
//                    userId, userName, deliveryNoteDO.getSupplierOrgId());
//        }
//        return list;
//    }

//    /**
//     * @Des 过账时判断是否是塔机并且尾差金额大于0，
//     * 将明细第一条拆成两条，数量（N）*单价变为：1*（单价+尾差金额），（N-1）*单价，
//     * 在SAP过账生成的销售订单和发货通知单都根据拆过的生成
//     * @Date 2020/11/11 15:47
//     * @Author wangzhaoyu
//     * @Param [deliveryNoteDO, detailDOList, companyInfoVO, userId, userName]
//     * @Return void
//     */
//    private List<Map<String,String>> tjSapPostParam(BigDecimal cashShortAndOver,DeliveryNoteDO deliveryNoteDO,List<DeliveryNoteDetailDO> detailDOList,CompanyInfoVO companyInfoVO,String userId,String userName){
//        List<Map<String, String>> result = new ArrayList<>();
//        for(int i = 0 ;i < detailDOList.size() ; i++){
//            DeliveryNoteDetailDO detailDO = detailDOList.get(i);
//            if(i == 0){//把第一条零件拆分
//                BigDecimal materialsQty ;//要过账的零件数量
//                if("0".equals(deliveryNoteDO.getIsOut())){
//                    materialsQty = detailDO.getDeliveryQty();
//                }else{
//                    if (detailDO.getInventoryOutAmount().equals(BigDecimal.ZERO)) {
//                        continue;
//                    }
//                    materialsQty = detailDO.getInventoryOutAmount();
//                }
//                //零件拆分
//                if(materialsQty.compareTo(new BigDecimal("1"))> 0){//n > 1 拆分成n-1 和 1
//                    Map<String, String> firstMapd = new HashMap<>();
//                    //拆分成两条记录  ①零件数量=1，价格为当前价格+尾差金额的记录
//                    BigDecimal onePostQty = BigDecimal.ONE;
//                    firstMapd.put(MATERIALS_QTY, onePostQty.toString());
//                    firstMapd.put(MATERIALS_NO, detailDO.getMaterialsNo());
//                    firstMapd.put(UNIT, detailDO.getUnit());
//                    firstMapd.put(PRICE, takeDecimals(detailDO.getUnitPriceAfterAdjust()).add(takeDecimals(cashShortAndOver)).toString());
//                    MarketingActivityDO marketingActivityDO = marketingActivityMapper.item(detailDO.getPriceSchemeId());
//                    if (marketingActivityDO == null && !StringUtil.isNullOrEmpty(detailDO.getPriceSchemeName())) {
//                        marketingActivityDO = marketingActivityMapper.findByName(companyInfoVO.getOrgId(), detailDO.getPriceSchemeName());
//                        if (marketingActivityDO != null) {
//                            firstMapd.put(PRICE_GROUP, marketingActivityDO.getPriceGroup());
//                        }
//                    } else {
//                        firstMapd.put(PRICE_GROUP, "");
//                    }
//                    result.add(firstMapd);
//                    //插入过账记录
//                    insertPostRecord(deliveryNoteDO.getId(), deliveryNoteDO.getDeliveryNo(), detailDO.getMaterialsNo(), onePostQty,
//                            userId, userName, deliveryNoteDO.getSupplierOrgId());
//                    //②零件数量-1，价格为当前价格
//                    Map<String, String> reduseMapd = new HashMap<>();
//                    BigDecimal redusePostQty = materialsQty.subtract(BigDecimal.ONE);
//                    reduseMapd.put(MATERIALS_QTY, redusePostQty.toString());
//                    reduseMapd.put(MATERIALS_NO, detailDO.getMaterialsNo());
//                    reduseMapd.put(UNIT, detailDO.getUnit());
//                    reduseMapd.put(PRICE, takeDecimals(detailDO.getUnitPriceAfterAdjust()).toString());
//                    if (marketingActivityDO == null && !StringUtil.isNullOrEmpty(detailDO.getPriceSchemeName())) {
//                        marketingActivityDO = marketingActivityMapper.findByName(companyInfoVO.getOrgId(), detailDO.getPriceSchemeName());
//                        if (marketingActivityDO != null) {
//                            reduseMapd.put(PRICE_GROUP, marketingActivityDO.getPriceGroup());
//                        }
//                    } else {
//                        reduseMapd.put(PRICE_GROUP, "");
//                    }
//                    result.add(reduseMapd);
//                    //插入过账记录
//                    insertPostRecord(deliveryNoteDO.getId(), deliveryNoteDO.getDeliveryNo(), detailDO.getMaterialsNo(), redusePostQty,
//                            userId, userName, deliveryNoteDO.getSupplierOrgId());
//
//                }else{//不拆分，直接提升单价
//                    Map<String, String> mapd = new HashMap<>();
//                    mapd.put(MATERIALS_QTY, materialsQty.toString());
//                    mapd.put(MATERIALS_NO, detailDO.getMaterialsNo());
//                    mapd.put(UNIT, detailDO.getUnit());
//                    mapd.put(PRICE, takeDecimals(detailDO.getUnitPriceAfterAdjust()).add(takeDecimals(cashShortAndOver)).toString());
//                    MarketingActivityDO marketingActivityDO = marketingActivityMapper.item(detailDO.getPriceSchemeId());
//                    if (marketingActivityDO == null && !StringUtil.isNullOrEmpty(detailDO.getPriceSchemeName())) {
//                        marketingActivityDO = marketingActivityMapper.findByName(companyInfoVO.getOrgId(), detailDO.getPriceSchemeName());
//                        if (marketingActivityDO != null) {
//                            mapd.put(PRICE_GROUP, marketingActivityDO.getPriceGroup());
//                        }
//                    } else {
//                        mapd.put(PRICE_GROUP, "");
//                    }
//                    result.add(mapd);
//                    //插入过账记录
//                    insertPostRecord(deliveryNoteDO.getId(), deliveryNoteDO.getDeliveryNo(), detailDO.getMaterialsNo(), detailDO.getInventoryOutAmount(),
//                            userId, userName, deliveryNoteDO.getSupplierOrgId());
//                }
//            }else{//不是第一条零件记录直接走正常的逻辑
//                Map<String, String> mapd = new HashMap<>();
//                if ("0".equals(deliveryNoteDO.getIsOut())) {
//                    mapd.put(MATERIALS_QTY, detailDO.getDeliveryQty().toString());
//                } else {
//                    if (detailDO.getInventoryOutAmount().equals(BigDecimal.ZERO)) {
//                        continue;
//                    }
//                    mapd.put(MATERIALS_QTY, detailDO.getInventoryOutAmount().toString());
//                }
//                mapd.put(MATERIALS_NO, detailDO.getMaterialsNo());
//                mapd.put(UNIT, detailDO.getUnit());
//                mapd.put(PRICE, takeDecimals(detailDO.getUnitPriceAfterAdjust()).toString());
//                MarketingActivityDO marketingActivityDO = marketingActivityMapper.item(detailDO.getPriceSchemeId());
//                if (marketingActivityDO == null && !StringUtil.isNullOrEmpty(detailDO.getPriceSchemeName())) {
//                    marketingActivityDO = marketingActivityMapper.findByName(companyInfoVO.getOrgId(), detailDO.getPriceSchemeName());
//                    if (marketingActivityDO != null) {
//                        mapd.put(PRICE_GROUP, marketingActivityDO.getPriceGroup());
//                    }
//                } else {
//                    mapd.put(PRICE_GROUP, "");
//                }
//                result.add(mapd);
//                //插入过账记录
//                insertPostRecord(deliveryNoteDO.getId(), deliveryNoteDO.getDeliveryNo(), detailDO.getMaterialsNo(), detailDO.getInventoryOutAmount(),
//                        userId, userName, deliveryNoteDO.getSupplierOrgId());
//            }
//        }
//        return result;
//    }

//    private void insertPostRecord(String billId, String billNo, String materialsNo, BigDecimal outAmount, String userId, String userName, String orgId) {
//        BigDecimal postQty = sapPostRecordMapper.getAllPostedQty(billId, billNo, materialsNo, null);
//        SapPostRecord record = new SapPostRecord();
//        record.setPostQty(outAmount.subtract(postQty));
//        record.setCreateTime(new Date());
//        record.setCreateName(userName);
//        record.setCreateId(userId);
//        record.setOrgId(orgId);
//        record.setMaterialsNo(materialsNo);
//        record.setId(fastGenClient.textGuid().getValue());
//        record.setBillType(billNo.substring(0, 4));
//        record.setBillNo(billNo);
//        record.setBillId(billId);
//        sapPostRecordMapper.insert(record);
//    }

//    @Transactional(rollbackFor = Exception.class)
//    public ErrorCode sapRemove(String id, String orgId) {
//        DeliveryNoteDO deliveryNoteDO = deliveryNoteMapper.item(id);
//        if (deliveryNoteDO == null) {
//            return ErrorCode.ImportExcelNoData;
//        }
//        if (StringUtils.isEmpty(deliveryNoteDO.getSapSaleOrder())) {
//            return ErrorCode.DeliveryNoteStateError;
//        }
//        CompanyInfoVO companyInfoVO = companyInfoService.info(orgId);
//        if (companyInfoVO == null || companyInfoVO.getSapCode() == null) {
//            LogHelper.error("删除sap过账单时企业不存在", ErrorCode.RequestIdError.getCode());
//            return ErrorCode.ImportExcelNoData;
//        }
//        ImportParam importParam = new ImportParam();
//        importParam.setFunction("ZPMS_DEL_SALEORDER");
//        Map<String, String> map = new HashMap<>();
//        map.put("VKORG", companyInfoVO.getSapCode());
//        //分销渠道，未知参数
//        //map.put("VTWEG",);
//        map.put("VBELN", deliveryNoteDO.getSapSaleOrder());
//        map.put("DELIV", deliveryNoteDO.getSapOutBill());
//
//        if (StringUtils.isNotBlank(deliveryNoteDO.getMaterialsNo())) {
//            map.put("MBLNR", deliveryNoteDO.getMaterialsNo());
//        }
//        Date postDate = sapPostRecordMapper.getLastPostTime(deliveryNoteDO.getDeliveryNo());
//        if (null == postDate) {
//            return ErrorCode.PostRecordNull;
//        }
//        SimpleDateFormat sdfYead = new SimpleDateFormat("yyyy");
//        SimpleDateFormat sdfYMD = new SimpleDateFormat("yyyyMMdd");
//        map.put("MJAHR", sdfYead.format(postDate));
//        map.put("BUDAT", sdfYMD.format(postDate));
//
//        importParam.setTable("RETURN");
//        importParam.setCommonParamMap(map);
//        importParam.setSapCode(companyInfoVO.getSapCode());
//        LogHelper.monitor("========调用删除sap过账单接口开始========");
//        OutputParam outputParam = SAPCommonUtil.getData(importParam);
//        LogHelper.monitor("========调用删除sap过账单接口结束========");
//        if (outputParam == null || outputParam.getCode() != 0) {
//            LogHelper.error("sap返回值为null", ErrorCode.SapReturnNull.getCode());
//            return ErrorCode.SapReturnNull;
//        }
//        if (outputParam.getDataList().size() > 0 && !outputParam.getDataList().get(0).get("TYPE").equals("S")) {
//            LogHelper.error("删除sap过账单失败|" + outputParam.getDataList().get(0).get("MESSAGE"), ErrorCode.SapUpdateFail.getCode());
//            return ErrorCode.SapUpdateFail;
//        }
//        if (outputParam.getDataHeader().get("RETURNCODE").equals(("S")) || outputParam.getDataHeader().get("RETURNCODE1").equals(("S"))
//                || outputParam.getDataHeader().get("RETURNCODE2").equals(("S"))) {
//            if (!StringUtil.isNullOrEmpty(outputParam.getDataHeader().get("RETURNCODE")) && !outputParam.getDataHeader().get("RETURNCODE").equals(("S"))) {
//                LogHelper.error("删除sap过账单失败|" + outputParam.getDataHeader().get("RETURNMSG") + outputParam.getDataHeader().get("RETURNMSG1") + outputParam.getDataHeader().get("RETURNMSG2"), ErrorCode.SapUpdateFail.getCode());
//                return ErrorCode.SapUpdateFail;
//            }
//            LogHelper.monitor(deliveryNoteDO.getDeliveryNo()+"执行了removeSap操作");
//            if (deliveryNoteMapper.removeSap(id) == 0) {
//                return ErrorCode.SapUpdateFail;
//            }
//            if (sapPostRecordMapper.removeByBusiness(id) == 0) {
//                return ErrorCode.SapUpdateFail;
//            }
//            //如果时塔机的主机厂，过账删除成功后需要更新发货通知单，销售订单，销售订单详情表的出库状态为未出库
//            String sapCode = companyInfoVO.getSapCode();
//            if(sapCode != null && CompanyUtil.TJ_SAP_CODE.equals(sapCode)){
//                sapPostRemoveSuccessUpdateOutStatus(deliveryNoteDO);
//            }
//            return ErrorCode.Success;
//        } else {
//            LogHelper.error("删除sap过账单失败|" + outputParam.getDataHeader().get("RETURNMSG") + outputParam.getDataHeader().get("RETURNMSG1") + outputParam.getDataHeader().get("RETURNMSG2"), ErrorCode.SapUpdateFail.getCode());
//            return ErrorCode.SapUpdateFail;
//        }
//    }

    /**
     * @Des sap删除过账成功后更新更新发货通知单，销售订单，销售订单详情表的出库状态为未出库
     * @Date 2020/12/2 10:26
     * @Author wangzhaoyu
     * @Param []
     * @Return void
     */
    private void sapPostRemoveSuccessUpdateOutStatus(DeliveryNoteDO deliveryNoteDO) {
        try {
            String id = deliveryNoteDO.getId();
            String outStatus = "0";
            String outStatusDesc = DeliveryNoteOutStatusEnum.getDescByStatus(outStatus);
            deliveryNoteMapper.updateIsOut(id, outStatus, outStatusDesc);
            String saleNo = deliveryNoteDO.getSaleNo();
            if (!StringUtils.isEmpty(saleNo)) {
                saleIntentionMapper.updateInventoryOutStatus(saleNo, outStatus);
                saleIntentionDetailMapper.updateInventoryOutStatus(saleNo, outStatus);
            }
        } catch (Exception e) {
            LogHelper.error("过账删除操作后更新发货通知单，销售订单，销售订单详情表的出库状态为未出库异常" + e, ErrorCode.Failure.getCode());
        }
    }

    /**
     * 手动完成单据<br>
     * materialsNo 不为null,则更改该单据下的零件状态为“手动完成”状态；如果materialsNo为空，则更改整个单据为“手动完成”状态
     *
     * @param billNo      String 单据编号
     * @param materialsNo String 零件编号
     * @param orgId       String 企业ID
     * @return ErrorCode 返回码
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode manualFinish(String billNo, String materialsNo, String orgId) throws Exception {
        DeliveryNoteDO deliveryNoteDO = deliveryNoteMapper.findByDeliveryNo(billNo, orgId);
        if (deliveryNoteDO == null) {
            return ErrorCode.IllegalArument;
        }
        if (deliveryNoteDO.getStatus().equals('0')) {
            return ErrorCode.NotFinishBill;
        }

        CompanyInfoVO info = companyInfoService.info(orgId);
        if (null != info && null != info.getIsSap() && 0 == info.getIsSap()) {
            if (0 != deliveryNoteDO.getCheckState()) {
                return ErrorCode.SettlementDataRedemptionWhenSettlementSalesReceiptStatement;
            }
        }

        boolean success = saleIntentionService.updateByManulFinish(deliveryNoteDO, materialsNo, orgId);
        if (!success) {
            throw new Exception("更新销售意向状态失败");
        }
        if (StringUtil.isNullOrEmpty(materialsNo))//零件编码为空，更新单据状态为“手动完成”
        {
            deliveryNoteMapper.updateStatus("3", "强制结单", billNo);
            warehouseDeliveryService.updateState(billNo, 3, orgId);
            deliveryNoteDO.setIsOut("3");
            deliveryNoteDO.setIsOutDesc(DeliveryNoteOutStatusEnum.getDescByStatus("3"));
            deliveryNoteDetailMapper.updateStatus("3", deliveryNoteDO.getId(), null);
            warehouseDeliveryDetailMapper.updateAllStatus(3, billNo, orgId);
        } else {
            deliveryNoteDetailMapper.updateStatus("3", deliveryNoteDO.getId(), materialsNo);
            warehouseDeliveryService.updateDetailState(billNo, materialsNo, null, 3, orgId);
            ErrorCode errorCode = checkBillFinished(billNo, deliveryNoteDO.getId(), orgId);

            if (ErrorCode.Success != errorCode) {
                return errorCode;
            }
        }
        updateTotalDiscountPrice(deliveryNoteDO);
        subtractReceiverPrice(billNo, orgId, deliveryNoteDO, info);
        return ErrorCode.Success;
    }

    //扣减预付款金额
    private void subtractReceiverPrice(String billNo, String orgId, DeliveryNoteDO deliveryNoteDO, CompanyInfoVO info) throws Exception {
        //2019-12-03 主机厂也需要调整金额
        /*if (null == info || null == info.getIsSap() || 0 != info.getIsSap()) {
            return;
        }*/
        BigDecimal remainPrice = BigDecimal.ZERO;//结算之后应收款
        BigDecimal oldTotalPrice = BigDecimal.ZERO;//结算之前总金额
        List<DeliveryNoteDetailDO> list = deliveryNoteDetailMapper.list(deliveryNoteDO.getId());
        if (ListUtil.isNullOrEmpty(list)) {
            return;
        }
        ArapDetailDO arapDetailDO = arapDetailMapper.selectByBillNo(orgId, billNo);
        if (null == arapDetailDO) {
            return;
        }

        for (DeliveryNoteDetailDO detailDO : list) {
            if ("3".equals(detailDO.getStatus())) {
                remainPrice = remainPrice.add(detailDO.getInventoryOutAmount().multiply(detailDO.getUnitPriceAfterAdjust()));
            } else {
                remainPrice = remainPrice.add(detailDO.getDeliveryQty().multiply(detailDO.getUnitPriceAfterAdjust()));
            }
            oldTotalPrice = oldTotalPrice.add(detailDO.getDeliveryQty().multiply(detailDO.getUnitPriceAfterAdjust()));
        }

        ArapDetailDO updateArapDetailDO = new ArapDetailDO();
        remainPrice = remainPrice.divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
        oldTotalPrice = oldTotalPrice.divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
        updateArapDetailDO.setRemainPrice(remainPrice);
        if (remainPrice.compareTo(BigDecimal.ZERO) == 0) {
            DeliveryNoteDO deliveryNote = new DeliveryNoteDO();
            deliveryNote.setCheckState(2);
            deliveryNote.setId(deliveryNoteDO.getId());
            deliveryNoteMapper.update(deliveryNote);
            updateArapDetailDO.setIsSettle(1);
        }
        updateArapDetailDO.setTotalPrice(remainPrice);
        updateArapDetailDO.setId(arapDetailDO.getId());
        int updateCount = arapDetailMapper.update(updateArapDetailDO);
        if (updateCount <= 0) {
            throw new Exception("扣减应收款详情金额失败");
        }

        //扣减应收主表欠款金额
        ArapDO updateRecord = new ArapDO();
        ArapDO arapDO = arapMapper.selectByAccOrgId(orgId, arapDetailDO.getPurchaseOrgId(), 0);
        updateRecord.setOldReceiverPrice(arapDO.getReceiverPrice());
        updateRecord.setReceiverPrice(arapDO.getReceiverPrice().subtract(oldTotalPrice).add(remainPrice));
        updateRecord.setId(arapDO.getId());
        int updateArapCount = arapMapper.updateSelective(updateRecord);
        if (updateArapCount <= 0) {
            throw new Exception("扣减应收款欠款金额失败");
        }
    }

    /**
     * 校验单据是否已完成<br>
     * 判断单据下的所有零件是否已经完成，如果都完成，则更改单据状态为完成
     *
     * @param billNo String
     * @param billId String
     * @param orgId  String
     * @return Boolean
     */
//    @Transactional(rollbackFor = Exception.class)
    private ErrorCode checkBillFinished(String billNo, String billId, String orgId) throws Exception {
        List<DeliveryNoteDetailDO> deliveryNoteDetailDOs = deliveryNoteDetailMapper.list(billId);
        if (ListUtil.isNullOrEmpty(deliveryNoteDetailDOs)) {
            throw new Exception("未查询到发货通知单详情列表");
        }
        boolean manul = false;
        boolean flag = true;
        int status;
        String statusDesc;
        for (DeliveryNoteDetailDO temp : deliveryNoteDetailDOs) {
            if ("3".equals(temp.getStatus())) {
                manul = true;
            }
            if ("2".equals(temp.getStatus()) || "3".equals(temp.getStatus())) {
                //完成状态
                continue;
            }
            flag = false;
        }
        if (flag) {
            if (manul) {
                status = 3;
                statusDesc = "强制结单";
            } else {
                status = 2;
                statusDesc = "已出库";
            }
        } else {
            status = 1;
            statusDesc = "部分出库";
        }
        deliveryNoteMapper.updateStatus(status + "", statusDesc, billNo);
        warehouseDeliveryService.updateState(billNo, status, orgId);
        return ErrorCode.Success;
    }

    private void updateTotalDiscountPrice(DeliveryNoteDO deliveryNoteDO) {
        List<DeliveryNoteDetailDO> list = deliveryNoteDetailMapper.list(deliveryNoteDO.getId());
        if (ListUtil.isNullOrEmpty(list)) {
            return;
        }
        BigDecimal totalPrice = BigDecimal.ZERO;
        for (DeliveryNoteDetailDO detailDO : list) {
            if ("3".equals(detailDO.getStatus())) {
                totalPrice = totalPrice.add(detailDO.getInventoryOutAmount().multiply(detailDO.getUnitPriceAfterAdjust()));
            } else {
                totalPrice = totalPrice.add(detailDO.getDeliveryQty().multiply(detailDO.getUnitPriceAfterAdjust()));
            }
        }
        deliveryNoteDO.setTotalDiscountPrice(totalPrice);
        deliveryNoteMapper.update(deliveryNoteDO);
    }

    @Transactional(rollbackFor = Exception.class)
    public ErrorCode addBySendBill(DeliveryNoteAddVO deliveryNoteAddVO, String orgId) throws Exception {
        Date now = new Date();
        DataDictionaryDO delivery = dataDictionaryMapper.itemByCode("WLZT", "0");
        DataDictionaryDO out = dataDictionaryMapper.itemByCode("INOUTSTATE", "1");
        //发货通知单增加
        DeliveryNoteDO deliveryNoteDO = new DeliveryNoteDO();
        BeanUtils.copyProperties(deliveryNoteAddVO.getHeaderInfo(), deliveryNoteDO);
        deliveryNoteDO.setTotalDiscountPrice(new BigDecimal(0));
        ActionResult<String> textNote = fastGenClient.textGuid();
        if (textNote.getCode() != ErrorCode.Success.getCode()) {
            return ErrorCode.IllegalArument;
        }
        CompanyDealerDO companyInfoVO = companyDealerMapper.itemByOrgId(orgId, deliveryNoteAddVO.getHeaderInfo().getPurchaseOrgId());
        if (companyInfoVO == null) {
            LogHelper.error("企业不存在", ErrorCode.RequestIdError.getCode());
            return ErrorCode.ImportExcelNoData;
        }
        if (companyInfoVO.getDealerCode() == null) {
            companyInfoVO.setDealerCode(deliveryNoteAddVO.getHeaderInfo().getPurchaseOrgId());
        }
        deliveryNoteDO.setSold(companyInfoVO.getDealerCode());
        deliveryNoteDO.setDelivery(companyInfoVO.getDealerCode());
        //内 部主键
        deliveryNoteDO.setId(textNote.getValue().toString());
        //发货通知单号
        if (StringUtil.isNullOrEmpty(deliveryNoteDO.getDeliveryNo())) {
            deliveryNoteDO.setDeliveryNo(genDocumentService.genDocumentNo(BillDesc.DeliveryNo, orgId));
        }
        //外向发货单号
        deliveryNoteDO.setSapOutNo(genDocumentService.getDeliveryNo());
        deliveryNoteDO.setAgentApplicationNo(genDocumentService.getDocumentNo(BillDesc.AgentApplicationNo));
        deliveryNoteDO.setSaleNo(deliveryNoteAddVO.getHeaderInfo().getSaleNo());
        deliveryNoteDO.setCustomerPurchaseDate(now);
        deliveryNoteDO.setCustomerPurchaseCode(deliveryNoteAddVO.getHeaderInfo().getCustomerPurchaseCode());
        if (delivery.getName() == null) {
            return ErrorCode.IllegalArument;
        } else {
            deliveryNoteDO.setLogState(delivery.getName());
        }
        //送货单自动生成的发货通知单直接设置审核状态为审核通过
        deliveryNoteDO.setReviewState(DeliveryNoteAuditStatusEnum.AUDIT_PASS.getAuditStatus());
        deliveryNoteDO.setAuditDate(now);
        deliveryNoteDO.setAuditUserId("00001");
        deliveryNoteDO.setAuditUserName("系统自动");
        deliveryNoteDO.setState(0);
        deliveryNoteDO.setTicketState(0);
        deliveryNoteDO.setIsOut("2");
        deliveryNoteDO.setIsOutDesc(DeliveryNoteOutStatusEnum.getDescByStatus("2"));
        deliveryNoteDO.setIsReverse(0);
        deliveryNoteDO.setIsPosting(0);
        deliveryNoteDO.setIsPrint(0);
        deliveryNoteDO.setModifyCode(deliveryNoteAddVO.getHeaderInfo().getCreatorId());
        deliveryNoteDO.setModifyDate(now);
        if (out.getName() == (null)) {
            return ErrorCode.IllegalArument;
        } else {
            deliveryNoteDO.setIsOutDesc(out.getName());
        }
        rounding(deliveryNoteDO);
        //发货通知详情增加
        for (DeliveryNoteDetailVO detail : deliveryNoteAddVO.getMaterialList()) {
            //本次发货数量不能大于剩余数量
            if ((detail.getSendQty().add(detail.getDeliveryQty())).compareTo(detail.getAmountAfterAdjust()) > 0) {
                return ErrorCode.DeliveryNoteQtyError;
            }
        }
        List<InformVO> informVOS = new ArrayList<>();
        for (DeliveryNoteDetailVO detail : deliveryNoteAddVO.getMaterialList()) {
            DeliveryNoteDetailDO detailDO = new DeliveryNoteDetailDO();
            BeanUtils.copyProperties(detail, detailDO);
            ActionResult<String> textNoteDetail = fastGenClient.textGuid();
            if (textNoteDetail.getCode() != ErrorCode.Success.getCode()) {
                return ErrorCode.IllegalArument;
            }
            detailDO.setId(textNoteDetail.getValue().toString());
            detailDO.setDeliveryNoteNo(deliveryNoteDO.getId());
            detailDO.setCreateCode(deliveryNoteDO.getCreatorId());
            detailDO.setIsDel(false);
            detailDO.setDeliveryQty(detailDO.getDeliveryQty());
            detailDO.setPrice(rounding(detailDO.getPrice()));
            detailDO.setApplyTotalPrice(detailDO.getQty().multiply(detailDO.getPrice()));
            detailDO.setAmountAfterAdjust(detailDO.getAmountAfterAdjust());
            detailDO.setUnitPriceAfterAdjust(rounding(detailDO.getUnitPriceAfterAdjust()));
            detailDO.setTotalPriceAfterAdjust(detailDO.getUnitPriceAfterAdjust().multiply(detailDO.getDeliveryQty()));
            detailDO.setOrgId(deliveryNoteDO.getSupplierOrgId());
            detailDO.setInventoryOutAmount(detailDO.getDeliveryQty());
            detailDO.setStatus("2");
            if (detailDO.getDeliveryDate() == null) {
                detailDO.setDeliveryDate(now);
            }
            deliveryNoteDO.setTotalDiscountPrice(deliveryNoteDO.getTotalDiscountPrice().add(detailDO.getTotalPriceAfterAdjust().setScale(0, BigDecimal.ROUND_HALF_UP)));

            if (detailDO.getDeliveryQty() == null) {
                return ErrorCode.DeliveryNoteDetailQtyDesc;
            } else {
                if (detailDO.getAmountAfterAdjust().compareTo(detailDO.getDeliveryQty()) < 0) {
                    return ErrorCode.DeliveryNoteDetailQty;
                }
            }
            SaleIntentionDetailDO saleIntentionDetailDO = saleIntentionDetailMapper.selectByNo(deliveryNoteAddVO.getHeaderInfo().getSaleNo(), detailDO.getMaterialsNo());
            if (saleIntentionDetailDO == null) {
                return ErrorCode.Failure;
            }
            InformVO informVO = new InformVO();
            informVO.setSaleNo(deliveryNoteAddVO.getHeaderInfo().getSaleNo());
            //订单总数量
            informVO.setAmount(detailDO.getAmountAfterAdjust());
            informVO.setMaterialsNo(detailDO.getMaterialsNo());
            //已发数量(本次发货数量+发运数)
            informVO.setInformedAmount(saleIntentionDetailDO.getInformedAmount().add(detailDO.getDeliveryQty()));
            informVOS.add(informVO);
            if (!String.valueOf(DeliveryStatus.Saved.getCode()).equals(deliveryNoteDO.getStatus())) {
                detailDO.setSendQty(informVO.getInformedAmount());
            }
            deliveryNoteDetailMapper.add(detailDO);

            saleIntentionService.updateByOutBound(deliveryNoteDO.getSaleNo(), detailDO.getMaterialsNo(), detailDO.getInventoryOutAmount(), orgId);
        }
        if (String.valueOf(DeliveryStatus.Saved.getCode()).equals(deliveryNoteDO.getStatus())) {
            deliveryNoteMapper.add(deliveryNoteDO);
        } else {
            deliveryNoteMapper.add(deliveryNoteDO);
            saleIntentionService.updateInformAmount(informVOS, deliveryNoteDO.getSupplierOrgId());
            updateSendQty(informVOS, deliveryNoteDO.getSupplierOrgId());

            //如果是代理商生成应收记录
            //2019-12-02 主机厂和代理商都从发货通知单新增应收记录
//            CompanyInfoVO infoVO = companyInfoService.info(deliveryNoteDO.getSupplierOrgId());
//            if (infoVO != null && (infoVO.getIsSap() == null || infoVO.getIsSap() == 0)) {
//                this.balanceAdd(deliveryNoteDO);
//            }
            this.balanceAdd(deliveryNoteDO);

        }
        return ErrorCode.Success;
    }


    /**
     * 判断是否允许过账
     * 不允许过账需要同时满足以下条件：
     * 1.主机厂是定义在表SYSTEM_PARAMETER,param_type中的DELIVERY_POST_COM对应的的公司
     * 2.客户是该主机厂对应的定义在表SYSTEM_PARAMETER,param_type中的DELIVERY_POST_DEALER对应的客户
     * 3.发货通知单尚未创建发运交接单或者发运交接单未发货
     *
     * @return
     */
    private boolean canPost(DeliveryNoteDO deliveryNoteDO) {
        if (!isNeedShipedCompany(deliveryNoteDO.getSupplierOrgId())) {
            return true;
        }
        if (!isNeedShipedDealer(deliveryNoteDO.getSupplierOrgId(), deliveryNoteDO.getPurchaseOrgId())) {
            return true;
        }
        return receiptIsShipped(deliveryNoteDO.getId());
    }

    /**
     * 判断发运交接单是否已发货：
     * 现在挖机操作都是只会生成一条发运交接单，如果多条，也只有一条有效，所以只要取到其中一条是已发货，说明发运交接单已发货。
     * 如后续业务扩展到其他厂家，可能需要调整为所有发运交接单都发货才算已发货
     *
     * @param deliveryNoteId
     * @return
     */
    private boolean receiptIsShipped(String deliveryNoteId) {
        List<String> receiptIds = deliveryReceiptLinkMapper.findReceiptIds(deliveryNoteId);
        if (CollectionUtils.isEmpty(receiptIds)) {
            return false;
        }
        for (String receiptId : receiptIds) {
            DeliveryReceiptDO deliveryReceiptDO = deliveryReceiptMapper.item(receiptId);
            if (deliveryReceiptDO.isShiped()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否过账方是否是参数POST_AFTER_DELIVERY_SEND_COM中定义的公司
     *
     * @param supplierOrgId
     * @return
     */
    private boolean isNeedShipedCompany(String supplierOrgId) {
        List<SystemParameter> needShipedComs = systemParameterService.listByParamType(POST_AFTER_DELIVERY_SEND_COM);
        return containsParam(needShipedComs, supplierOrgId);
    }

    /**
     * 判断发货通知单客户方是否是参数POST_AFTER_DELIVERY_SEND_DEALER中定义的客户
     *
     * @param supplierOrgId
     * @param purchaseOrgId
     * @return
     */
    private boolean isNeedShipedDealer(String supplierOrgId, String purchaseOrgId) {
        List<SystemParameter> needShipedDealers = systemParameterService.listByParamType(POST_AFTER_DELIVERY_SEND_DEALER, supplierOrgId);
        return containsParam(needShipedDealers, purchaseOrgId);
    }

    private boolean containsParam(List<SystemParameter> sourceParameters, String target) {
        if (CollectionUtils.isEmpty(sourceParameters)) {
            return false;
        }
        for (SystemParameter parameter : sourceParameters) {
            if (target.equals(parameter.getParamValue())) {
                return true;
            }
        }
        return false;
    }

    /**
     * @Author: WangKe
     * @Description: 更新是否就绪状态
     * @Date: 2019/1/25 0025
     */
    public ErrorCode updateIsReady(List<String> ids) throws Exception {
        int num = deliveryNoteMapper.findNotSubmit(ids);
        if (num > 0) {
            throw new Exception("存在未提交的发货通知单");
        }
        return deliveryNoteMapper.updateIsReady(ids) > 0 ? ErrorCode.Success : ErrorCode.Failure;
    }


    public DeliveryNoteVO itemDetail(String billNo, String orgId, String materialsNo) {
        DeliveryNoteDO deliveryNoteDO = deliveryNoteMapper.itemByNo(billNo, orgId);
        DeliveryNoteDetailDO deliveryNoteDetailDO = deliveryNoteDetailMapper.itemByMaterialsNo(deliveryNoteDO.getId(), materialsNo);
        DeliveryNoteVO deliveryNoteVO = new DeliveryNoteVO();
        deliveryNoteVO.setCountry(deliveryNoteDO.getCountry());
        deliveryNoteVO.setPurchaseContractNo(deliveryNoteDO.getPurchaseContractNo());
        if (deliveryNoteDetailDO != null) {
            deliveryNoteVO.setMachineModel(deliveryNoteDetailDO.getMachineModel());
            deliveryNoteVO.setOriginalMaterialsNo(deliveryNoteDetailDO.getOriginalMaterialsNo());
        }

        return deliveryNoteVO;
    }

    /**
     * @Des 查询当前机构未删除，已提交的待审核数据
     * @Date 2021/4/13 11:27
     * @Author wangzhaoyu
     * @Param [orgId]
     * @Return java.lang.Integer
     */
    public Integer countAuditData(String orgId) {
        Integer count = deliveryNoteMapper.countAuditData(orgId);
        return count == null ? 0 : count;
    }
}

